실생활 예 - UseImperativeHandle
17653 단어 hookswebdevjavascriptreact
1. 잠깐만요...뭐죠?
useImperativeHandle
를 사용하면 ref
를 사용하여 자식 구성 요소에서 부모로 값과 함수를 전달할 수 있습니다.거기에서 부모는 그것을 스스로 사용하거나 다른 자식에게 전달할 수 있습니다.
Note that you can only pass a ref as a prop to a child that wraps its component in
forwardRef
.
코드 예제는 이해에 있어 단어보다 훨씬 낫습니다. 그래서 여기에 그 중 하나가 있습니다.
// Parent Component
const App = () => {
const ref = useRef();
return (
<div>
<ComponentWithButton ref={ref} />
<button onClick={() => ref.current.increment()}>another button</button>
</div>
);
};
// Child Component
const ComponentWithButton = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({increment}))
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
return (
<div>
<button onClick={increment}>click</button>
<h2>Count: {count}</h2>
</div>
)
})
위의 예에서
useImperativeHandle
및 forwardRef
의 도움으로 상위 구성 요소의 카운트 변수를 변경하고 있습니다.2. 왜?
React의 일반적인 패턴은 단방향 데이터 흐름을 갖는 것입니다.
양방향 데이터 흐름이 필요한 경우
Redux
또는 React context
와 같은 라이브러리를 사용할 수 있습니다.그러나 어떤 경우에는 그것들을 사용하는 것이 단순히 과잉입니다.
이것은
useImperativeHandle
가 들어오는 곳입니다.이제 우리는 후크에 대해 어느 정도 이해했으며 이를 사용하고 싶을 때 실제 사례로 이동하겠습니다...
사용자가 자신의 정보 및 알림 기본 설정을 업데이트하고 편집할 수 있는 페이지
Settings
가 있습니다.구성 요소에는
sections
가 있으며 모든 섹션은 사용자와 관련된 데이터 변경을 담당하는 양식입니다(프로필 정보, 개인 정보 설정 및 알림 설정에 대한 섹션).const Section = ({ name, text, fields, schema }) => {
const { control, handleSubmit, reset, formState } = useForm({
mode: 'onChange',
defaultValues: fields.reduce((acc, field) => ({ ...acc, [field.name]: field.defaultValue }), {})
});
return (
<section className={styles.section}>
<Title text={text} />
<form onSubmit={handleSubmit(onSubmit)}>
{fields.map(field => (
<Field key={field.name} {...field} control={control} />
))}
</form>
</section>
);
};
모든
section
는 Settings
구성 요소인 상위 구성 요소에서 렌더링됩니다.const Settings = () => (
<main className={styles.main}>
{SECTIONS.map(section => (
<Section key={section.name} {...section} />
))}
</main>
);
아마도 자식을 렌더링하는 부모 구성 요소는 모든 것이 괜찮을 것입니다. 하지만 전역 버튼을 클릭하여 모든 섹션의 제출 기능을 트리거하려면 어떻게 해야 할까요?
우리는 부모가 통제할 수 있는 방법이 필요할 것입니다.
useImperativeHandle
가 들어오는 곳입니다.Section
구성 요소에 후크를 추가하고 정방향 참조로 래핑하여 Settings
에서 참조를 전달할 수 있도록 합니다.const Section = React.forwardRef(({ name, text, fields, schema },ref) => {
const { control, handleSubmit, reset, formState } = useForm({
mode: 'onChange',
defaultValues: fields.reduce((acc, field) => ({ ...acc, [field.name]: field.defaultValue }), {})
});
useImperativeHandle(ref, () => ({
submit() {
handleSubmit(onSubmit)();
}
}));
return (
<section className={styles.section}>
<Title text={text} />
<form onSubmit={handleSubmit(onSubmit)}>
{fields.map(field => (
<Field key={field.name} {...field} control={control} />
))}
</form>
</section>
);
});
후크의 도움으로 우리는 부모가 사용할 일종의 API를 만들 수 있습니다. 이 예에서는 우리가 호출할 수 있는
submit()
함수를 노출합니다.이제
Settings
구성 요소는 다음과 같습니다.const Settings = () => {
const refProfile = useRef();
const refNotifications = useRef();
const refPrivacy = useRef();
// The SECTIONS object is a configuration object that will
// hold the refs among the rest of the data
const onSubmitAll = () => {
SECTIONS.forEach(({ ref }) => {
ref.current.submit();
});
};
return (
<main className={styles.main}>
{SECTIONS.map(section => (
// The ref of each section i passed here in the spread
// operation.
<Section key={section.name} {...section} />
))}
</main>
);
}
그게 다야! 우리는 해냈다!
더 복잡한 라이브러리를 가져오거나 사용하지 않고 컨트롤을 부모에게 다시 전달했습니다.
3. 결론
실망시키려는 의도는 아니지만 React는 이 후크를 사용하는 것을 권장하지 않습니다. (후크를 사용하지 않고 이 작업을 수행할 수 있는 다른 방법이 있을 가능성이 큽니다.)
전체 공개, 결국 구성 요소 구조 변경
하지만! 그럼에도 불구하고 거의 사용되지 않는 이 신비한 후크에 대해 배우는 것은 매우 재미있었습니다.
여러분도 즐거우셨길 바래요🙏🏼 읽어주셔서 감사합니다!!
Reference
이 문제에 관하여(실생활 예 - UseImperativeHandle), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/danielbellmas/real-life-example-useimperativehandle-34k텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)