Пересылка Refs - это метод передачи ref через компонент одному из его потомков. Этот метод может быть особенно полезен для компонентов более высокого порядка (также известных как HOC).
Начнем с примера HOC, который регистрирует реквизиты компонента на консоли:
function logProps(WrappedComponent) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}
render() {
return <WrappedComponent {...this.props} />;
}
}
return LogProps;
}
«LOGProps» HOC проходит propsчерез весь компонент, который он обертывает, поэтому визуализированный вывод будет таким же. Например, мы можем использовать этот HOC для регистрации всех реквизитов, которые передаются нашему компоненту «причудливой кнопки»:
class FancyButton extends React.Component {
focus() {
// ...
}
// ...
}
// Rather than exporting FancyButton, we export LogProps.
// It will render a FancyButton though.
export default logProps(FancyButton);
В приведенном выше примере есть одно предостережение: refs не пройдет. Это потому, что ref это не опора. Как key, Реакт по-разному обрабатывается по-разному. Если вы добавите ref в HOC, ref будет ссылаться на внешний контейнерный компонент, а не на завернутый компонент.
Это означает, что ссылки, предназначенные для нашего FancyButton компонента, будут фактически привязаны к LogProps компоненту:
import FancyButton from './FancyButton';
const ref = React.createRef();
// The FancyButton component we imported is the LogProps HOC.
// Even though the rendered output will be the same,
// Our ref will point to LogProps instead of the inner FancyButton component!
// This means we can't call e.g. ref.current.focus()
<FancyButton
label="Click Me"
handleClick={handleClick}
ref={ref}
/>;
К счастью, мы можем явно перенаправить ссылки на внутренний FancyButton компонент с помощью React.forwardRefAPI. React.forwardRef принимает функцию рендеринга, которая получает props и ref параметры, и возвращает узел React. Например:
function logProps(Component) {
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps);
console.log('new props:', this.props);
}
render() {
const {forwardedRef, ...rest} = this.props;
// Assign the custom prop "forwardedRef" as a ref
return <Component ref={forwardedRef} {...rest} />;
}
}
// Note the second param "ref" provided by React.forwardRef.
// We can pass it along to LogProps as a regular prop, e.g. "forwardedRef"
// And it can then be attached to the Component.
function forwardRef(props, ref) {
return <LogProps {...props} forwardedRef={ref} />;
}
// These next lines are not necessary,
// But they do give the component a better display name in DevTools,
// e.g. "ForwardRef(logProps(MyComponent))"
const name = Component.displayName || Component.name;
forwardRef.displayName = `logProps(${name})`;
return React.forwardRef(forwardRef);
}
0 комментариев