너무 많은 일을 하는 React 구성 요소(및 이를 단순화하는 방법)
렌더링 조건을 지정하는 플래그 역할을 하는 새로운 부울 소품을 추가했던 때를 기억하십니까? 이런 일이 많이 발생하지만 이러한 작은 변화가 때때로 미래에 큰 영향을 미칠 수 있습니다.
기능 후 기능, 변경 후 변경, 구성 요소는 더 복잡해지는 경향이 있습니다. 우리가 그것을 주시하지 않는다면 그것들은 통제 불능이 될 것이고 그것은 우리로 하여금 변화를 두려워하게 만들 것입니다.
그렇기 때문에 구성 요소 계약에 주의해야 합니다. 그런데 그 계약은 소품을 통해 표현된다.
궁극적인 문제를 발견하는 한 가지 방법은 부울 소품(they will yell at you as you can read here)을 찾는 것입니다. 일반적인 경우는 렌더링 조건을 지정하는 방법으로 부울 소품을 사용하는 것입니다.
이 접근 방식에는 몇 가지 문제가 있습니다.
한 번 보자.
복잡한 계약
사용자가 사용자 이름을 사용하여 로그인할 수 있는 로그인 구성 요소를 만들어야 한다고 상상해 보십시오.
import React from "react";
function Login() {
return (
<div className="Login">
<form>
<p>
<label>Username:</label>
<input type="text" />
</p>
<p>
<label>Password:</label>
<input type="password" />
</p>
<p>
<input type="submit" value="Log In" />
</p>
</form>
</div>
);
}
export default Login;
어느 날 로그인 구성 요소를 검토하여 소비자가 사용자 이름 또는 이메일을 사용하여 로그인할지 여부를 결정할 수 있도록 해야 합니다. 이를 달성하기 위한 빠른 수정은 소비자가 이메일을 선호하는 경우 boolean prop으로 구성 요소를 만드는 것입니다.
import React from "react";
import PropTypes from "prop-types";
function Login({ usingEmail }) {
return (
<div className="Login">
<form>
<p>
<label>{usingEmail ? "Email:" : "Username:"}</label>
<input type={usingEmail ? "email" : "text"} />
</p>
<p>
<label>Password:</label>
<input type="password" />
</p>
<p>
<input type="submit" value="Log In" />
</p>
</form>
</div>
);
}
Login.propTypes = {
usingEmail: PropTypes.bool,
};
export default Login;
이제 언젠가 사용자가 전화번호로도 로그인할 수 있다고 상상해 보십시오. 이제 문제가 생겼습니다.
부울 플래그는 세 가지 변형을 지원하도록 확장할 수 없으며 동일한 전략에 따라 모순되는 부울 소품을 얻게 됩니다. 구성 요소 소비자는 예를 들어 사용자 이름과 전화 로그인으로 구성 요소를 구성할 수 있습니다.
import React from "react";
import PropTypes from "prop-types";
function Login({ usingEmail, usingPhoneNumber }) {
return (
<div className="Login">
<form>
<p>
<label>
{usingEmail ? "Email:" : usingPhoneNumber ? "Phone" : "Username:"}
</label>
<input
type={usingEmail ? "email" : usingPhoneNumber ? "tel" : "text"}
/>
</p>
<p>
<label>Password:</label>
<input type="password" />
</p>
<p>
<input type="submit" value="Log In" />
</p>
</form>
</div>
);
}
Login.propTypes = {
usingEmail: PropTypes.bool,
usingPhoneNumber: PropTypes.bool,
};
export default Login;
부울 플래그가 있는 계약은 복잡하고 소비자에게 나쁜 UX를 제공합니다.
구성 요소 서명을 복잡하게 만들고 이 구성 요소가 한 가지 이상의 작업을 수행한다고 소리칩니다. 플래그가 "True"이면 한 가지 작업을 수행하고 플래그가 "False"이면 다른 작업을 수행합니다. 이 예에서 최악의 상황은 소비자가 두 props가 모두 "True"일 때 무엇을 기대해야 할지 모른다는 것입니다.
그래서 뭘 할건데?
간단한 해결책은 부울보다 열거형을 선호하는 것입니다. 부울은 확장 가능하며 명확한 의도를 설명합니다.
import React from "react";
import PropTypes from "prop-types";
const USER_IDENTIFIFICATION_TYPES = {
USERNAME: "username",
EMAIL: "email",
PHONENUMBER: "phone",
};
function Login({ userIdentificationType }) {
const shouldUseEmail =
userIdentificationType === USER_IDENTIFIFICATION_TYPES.EMAIL;
const shouldUsePhone =
userIdentificationType === USER_IDENTIFIFICATION_TYPES.PHONENUMBER;
return (
<div className="Login">
<form>
<p>
<label>
{shouldUseEmail ? "Email:" : shouldUsePhone ? "Phone" : "Username:"}
</label>
<input
type={shouldUseEmail ? "email" : shouldUsePhone ? "tel" : "text"}
/>
</p>
<p>
<label>Password:</label>
<input type="password" />
</p>
<p>
<input type="submit" value="Log In" />
</p>
</form>
</div>
);
}
Login.propTypes = {
userIdentificationType: PropTypes.oneOf(
Object.values(USER_IDENTIFIFICATION_TYPES)
),
};
Login.defaultProps = {
userIdentificationType: USER_IDENTIFIFICATION_TYPES.USERNAME,
};
export default Login;
보시다시피 계약 문제를 수정했지만 이 구성 요소가 너무 많은 작업을 수행하고 있습니다.
신 구성 요소
계약 복잡성 외에도 부울 소품은 구성 요소가 너무 많은 일을 하는 신 구성 요소일 수 있다는 증상입니다.
그래서 뭘 할건데?
신의 구성 요소가 있다는 것을 알게 되면 구성 요소를 분리해야 합니다.
이 로그인 구성 요소 예제에서는 예를 들어 다음과 같은 내부 세부 정보를 캡슐화하기 위해 세 가지 구성 요소를 만들 수 있습니다.
기본 로그인 구성 요소
import React from "react";
import PropTypes from "prop-types";
function Login({ children }) {
return (
<div className="Login">
<form>
<p>{children}</p>
<p>
<label>Password:</label>
<input type="password" />
</p>
<p>
<input type="submit" value="Log In" />
</p>
</form>
</div>
);
}
Login.propTypes = {
children: PropTypes.node,
};
export default Login;
사용자 이름 로그인 구성 요소
import React from "react";
import Login from "./Login";
function UsernameLogin() {
return (
<Login>
<label>Username:</label>
<input type="text" />
</Login>
);
}
export default UsernameLogin;
이메일 로그인 구성 요소
import React from "react";
import Login from "./Login";
function EmailLogin() {
return (
<Login>
<label>EmailLogin:</label>
<input type="email" />
</Login>
);
}
export default EmailLogin;
전화 로그인 구성 요소
import React from "react";
import Login from "./Login";
function PhoneNumberLogin() {
return (
<Login>
<label>Phone:</label>
<input type="tel" />
</Login>
);
}
export default PhoneNumberLogin;
이렇게 하면 구성 요소가 한 가지 작업을 잘 수행할 수 있습니다.
도움이 되었기를 바랍니다. 이와 같은 더 많은 팁을 얻으려면 저를 팔로우하고 계속 연락합시다!
Reference
이 문제에 관하여(너무 많은 일을 하는 React 구성 요소(및 이를 단순화하는 방법)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/gsferreira/react-components-doing-too-much-and-how-to-simplify-them-4cnd텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)