React.useImperativeHandle의 구체적인 예
11794 단어 reacthooksjavascript
대부분의 경우 필요하지 않으며 문서에서도 더 선언적인 솔루션을 선택하여 사용을 권장하지 않습니다.
댄 아브라모프
당신이 초보자라면 그 중 절반이 필요하지 않습니다. (ImperativeHandle을 사용하려는 이유는 무엇입니까?) 기본 항목에 충실하십시오. 🙂 나중에 다른 것이 필요하다는 것을 알게 되면 그들은 당신을 위해 거기에 있습니다.
오후 13:18 - 2019년 1월 27일
때로는 유용할 수 있습니다. 이 게시물에서는 우리@Cloudinary가 최근에 발견한 한 가지 용도를 보여주고자 합니다.
자세히 보기
먼저 후크의 구현을 자세히 살펴보겠습니다.
다른 후크와 마찬가지로 실제 구현은 반응이 아닌 react-dom 패키지의 일부로 게시됩니다.
function imperativeHandleEffect(create, ref) {
if (typeof ref === 'function') {
ref(create());
} else if (ref !== null && ref !== undefined) {
ref.current = create();
}
}
위의 코드는 매우 간단합니다. 실제 코드는 here 입니다.
이 함수는 mountEffect()에 의해 래핑되며 이는 useEffect와 동일하게 실행됨을 의미합니다.
보시다시피 useImperativeHandle은
create
함수를 실행하고 이를 ref
매개변수에 할당합니다. 함수이면 입력으로 전달되고 그렇지 않으면 .current 값이 됩니다.useImperativeHandle accepts a dependency list, as with other hooks. However, React will actually add the
ref
to the list of dependencies for you but eslint-plugin-react-hooks doesnt seem to know that.
도전
그렇다면 ReactJS가 제공하는 간단한 예제 외에 무엇을 할 수 있을까요?
우리의 경우에는 디자인 시스템의 일부로 자체 UI 구성 요소를 구축하고 있습니다.
새 구성 요소인 NumberField로 래핑한 TextField 구성 요소가 있습니다. 대부분의 경우 NumberField는 Text 대응 항목과 매우 유사합니다. 그러나 우리는 위/아래 버튼에 대해 일관된 동작과 룩앤필을 원했습니다.
그러나 이들은 브라우저 간에 다르게 보이므로 자체 UI가 필요했습니다.
그런 다음 도전적인 부분이 왔습니다. controlled component 에 강제로 넣지 않고 React-land의 입력 값을 어떻게 제어합니까? 구성 요소의 사용은 제어 여부를 결정해야 합니다. 따라서 구성 요소 자체는 안됩니다.
제 동료가 매우 유용한 HTMLInputElement.stepUp() 및 HTMLInputElement.stepDown() 방법을 알려 주었습니다. 이는
value
를 전달하지 않고 입력 값을 변경할 수 있음을 의미했습니다.엄청난!
그러나 NumberField는 TextField를 래핑합니다. 따라서 내부 TextField에 외부 참조를 전달하는 동안 자체 참조를 사용할 수 있어야 합니다.
또 다른 제약 - ref는 함수일 수도 있고 객체일 수도 있습니다(useRef의 결과). 따라서 우리는 둘 다 지원해야 합니다(익숙하게 들리나요?).
여기서 useImperativeHandle이 도움이 됩니다. 그것 없이는 문제를 해결할 수 없는 것은 아닙니다. 솔루션을 매우 간결한 하나의 라이너로 줄였습니다. 우!
암호
먼저 TextInput을 정의합니다. 물론 이 문서의 목적을 위해 단순화되었습니다.
const TextInput = forwardRef(
({ type = "text", defaultValue, value, onChange, className }, ref) => {
return (
<input className={className} type={type} ref={ref} value={value} defaultValue={defaultValue} onChange={onChange} />
);
}
);
다음으로 기본 위/아래 버튼을 숨길 숫자 입력용 컨테이너를 정의합니다.
const NumberInputWrapper = styled.div`
display: flex;
input[type="number"] {
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
appearance: textfield;
}
`;
마지막으로 NumberInput을 정의합니다.
const NumberInput = forwardRef((props, ref) => {
const internalRef = useRef(null);
useImperativeHandle(ref, () => internalRef.current, []);
const onUp = useCallback(() => {
internalRef.current.stepUp();
}, [internalRef]);
const onDown = useCallback(() => {
internalRef.current.stepDown();
}, [internalRef]);
return (
<NumberInputWrapper>
<TextInput {...props} type="number" ref={internalRef} />
<NumberButtonsContainer>
<NumberButton onClick={onUp}>⬆️</NumberButton>
<NumberButton onClick={onDown}>⬇️</NumberButton>
</NumberButtonsContainer>
</NumberInputWrapper>
);
});
물론 위 코드에서 중요한 부분은 useImperativeHandle에 대한 호출입니다.
useImperativeHandle(ref, () => internalRef.current, []);
첫 번째 인수는 외부에서 받은 ref입니다.
create
함수 내에서 내부 참조의 결과를 반환합니다. 이렇게 하면 외부 코드에서 이전과 같이 ref를 사용할 수 있습니다. 내부적으로는 internalRef 인스턴스를 사용하여 DOM을 통해 입력을 변경할 수 있습니다.단순한!
추신 전체 코드 예제는 여기codesandbox에서 찾을 수 있습니다.
Reference
이 문제에 관하여(React.useImperativeHandle의 구체적인 예), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/poeticgeek/concrete-example-for-react-useimperativehandle-52l8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)