💡 Render props pattern 이란?
render props는 코드의 재사용성을 높임과 동시에, 관심사의 분리를 이룰 수 있도록 만들어주는 패턴 render props란 props에 넘겨주는 값이 JSX요소를 반환하는 함수는 prop을 말한다.
<Title render={() => <h1>hello world</h1>} />
render 라는 prop에 JSX Element를 반환하는 함수를 넣어 사용한다.
const Title = ({ render }) => render();
예시
drawing dream 프로젝트에서 회원가입 시 입력 값에 대해 유효성 검사를 진행하였다.
render props pattern을 적용하기 전 프로젝트의 구조
SignUp.js
└ InputContainer.js
├ Input.js
└ ValidContainer.js
SignUp.js 에 회원가입에 필요한 정보 뿐만 아니라 검사 결과에 해당하는 값을 저장하는 state까지 SignUp.js의 책임 이상의 데이터를 할당하고 있다. 또한 Input.js와 VslidContainer.js 두가지 컴포넌트를 묶어 두기위한 InputContainer.js라는 컴포넌트를 추가하여 사용하였다.
책임의 관점에서 각 컴포넌트를 바라보면
SignUp.js: 회원 가입을 하라
Input.js: 정보를 입력 받아라
ValidContainer: 유효성 검사를 하라
라고 결정하였고 이 관점에서 새로운 구조를 설계해보면
SignUp.js
├ Input.js
└ ValidationText.js
로 변경할 수 있었다.
새로 작성한 코드
Input.tsx
import React, { useState } from 'react';
type InputType = {
render?: (value: string) => JSX.Element;
}
const Input = ( { render } : InputType) => {
const [value, setValue] = useState<string>("");
const handelChange = (inputValue: string) => {
setValue(inputValue)
}
return (
<>
<input value={value} onChange={e => handelChange(e.target.value)} />
{render && render(value)}
</>
);
};
export default Input;
ValidationText.tsx
import React, { useEffect, useState } from 'react';
enum errorValue {
init = "",
error = "8 ~ 12자리 영문 대소문자와 숫자로 입력해주세요."
}
type validationTextType = {
value: string
}
const ValidationText = ({ value }: validationTextType) => {
const [error, setError] = useState<errorValue>(errorValue.init);
useEffect(() => {
const regExp = /^[a-zA-Z0-9]{8,12}$/;
if (!regExp.test(value)) {
setError(errorValue.error);
} else {
setError(errorValue.init);
}
}, [value])
return (
<div>
{ error }
</div>
);
};
export default ValidationText;
App.tsx
import { useEffect, useState } from "react";
import Input from "./components/Input/Input";
import ValidationText from "./components/Input/ValidationText";
function App() {
return (
<>
<Input
render={(value: string) => (
<>
<ValidationText value={value} />
</>
)}
/>
<Input />
</>
);
}
export default App;
결과
Input.js 와 ValidationText.js를 묶어 두기 위한 새로운 컴포넌트를 설계하지 않아도 되는 장점이 있음.
Input.js 재사용성 증가와 유연한 설계가 가능함.
책임의 관점으로 조금더 명확한 캡슐화가 가능함.
단, 결국 유효성 검사를 한 결과를 SignUp.js에게 전달 하여하는 것을 동일함. ContextAPI 또는 전역 상태 관리 라이브러리 등을 사용하여 좀더 유연한 대처가 가능할 수 있도록 설계하는 것이 좋을 것 같음.
'FRONT-END > REACTJS' 카테고리의 다른 글
StoryBook (0) | 2022.03.05 |
---|---|
리덕스 라이브러리 (0) | 2022.02.19 |
Context API (0) | 2022.02.19 |
react 비동기 작업 (0) | 2022.02.19 |
react route로 SPA 개발 (0) | 2022.02.19 |