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

时间:2018-11-08 02:40:07

标签: javascript reactjs

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

tl / dr:本质上,我想forward the refConsumer到实际组件。

这是一个具体的例子。 RootComponent设置CoolProvider的值,假定该值在所有 wrapped 子组件上公开。子组件使用withCool()包装,因此可以访问props.cool。 (当然,在一个现实世界的示例中,一切都更加复杂,并且包含数十个组件。)

现在,独立于是否知道子组件是否已包装,我希望能够通过ref()获得对它的引用,如RootComponent所示,但是不幸的是,被包装的组件不支持{{ 1}}可以正常使用了!

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

我的问题是:是否可以将引用请求从ref()转发到实际组件,以便父组件可以访问其引用?

CoolConsumer

2 个答案:

答案 0 :(得分:3)

我知道了!使用React的forwardRef API,可以实现我一直在寻找的东西。唯一需要的更改是替换

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

使用

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

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

答案 1 :(得分:-1)

ref就像key一样,它不是道具

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

const withCool = Component => props => {
  const {myRef, ...rest} = props;
  return (
    <CoolConsumer>
      {cool => <Component ref={myRef} {...rest} 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 myRef={(c) => { console.log('Cool child ref', c); }}/>
      </CoolProvider>
    );
  }
}

ReactDOM.render(<RootComponent />, document.querySelector('#cool'));