反应上下文使用者如何访问对使用者组件的引用

F L*_*has 3 javascript reactjs

我已经使用React新上下文API构建了一个更高阶的组件并且我试图找到一种方法(能够通过ref()包装子组件访问该引用)。

tl / dr:本质上,我想将ref转发Consumer到实际组件。

这是一个具体的例子。该RootComponent集的值CoolProvider是假设在所有被曝光包裹子组件。子组件使用进行包装withCool(),使其可以访问props.cool。(当然,在一个现实世界的示例中,一切都更加复杂,并且包含数十个组件。)

现在,不知道子组件是否已被包装,我希望能够通过对其进行引用,ref()如图所示,RootComponent但是不幸的是,被包装的组件ref()不再起作用,因为它们已经起作用了!

观看此现场演示(https://jsfiddle.net/64t0oenz/3/)并检查Web控制台。您将看到仅触发了非包装组件的回调。

我的问题是:有没有办法将参考请求从转发CoolConsumer到实际组件,以便父组件可以访问其参考?

const { Provider: CoolProvider, Consumer: CoolConsumer } = React.createContext();

const withCool = Component => props => (
  <CoolConsumer>
    {cool => <Component {...props} cool={cool} />}
  </CoolConsumer>
);

class ChildComponent extends React.Component {
  render() {
    return this.props.cool ? (
        <div>Isn't this cool?</div>
    ) : (
      <div>Not so cool!</div>
    );
  }
}

const CoolChildComponent = withCool(ChildComponent);

class RootComponent extends React.Component {
  render() {
    return (
        <CoolProvider value={true}>
        <ChildComponent ref={(c) => { console.log('Normal child ref', c); }}/>
        <CoolChildComponent ref={(c) => { console.log('Cool child ref', c); }}/>
      </CoolProvider>
    );
  }
}

ReactDOM.render(<RootComponent />, document.querySelector('#cool'));
Run Code Online (Sandbox Code Playgroud)

F L*_*has 5

我想到了!使用React的forwardRefAPI,可以实现我一直在寻找的东西。唯一需要的更改是更换

const withCool = Component => props => (
  <CoolConsumer>
    {cool => <Component {...props} cool={cool} />}
  </CoolConsumer>
);
Run Code Online (Sandbox Code Playgroud)

const withCool = Component => React.forwardRef((props, ref) => (
  <CoolConsumer>
    {cool => <Component {...props} cool={cool} ref={ref} />}
  </CoolConsumer>
));
Run Code Online (Sandbox Code Playgroud)

这是修改后的实时演示:https : //jsfiddle.net/64t0oenz/4/ 打开dev控制台,您现在将看到2个控制台日志,其中打印了对正常和酷组件的引用。