javascript - 无法将 ref 分配给渲染 Prop 中的组件

标签 javascript reactjs

假设您有一个简单的 React 应用程序(参见我的 codesandbox ):

import React from 'react';
import { render } from 'react-dom';

class RenderPropComponent extends React.Component {
  render() {
    console.log(this.example.test());
    return this.props.render();
  }
}

class Example extends React.Component {
  test = () => console.log('Test successful!');

  render() {
    return <h1>I am an example!</h1>;
  }
}

const App = () => (
  <RenderPropComponent
    render={() => {
      return (
        <Example ref={node => this.example = node} />
      )
    }}
  />
);

render(<App />, document.getElementById('root'));

这会导致错误:

TypeError
Cannot read property 'test' of undefined

如何将 ref 分配给通过 render prop 渲染的组件?

我知道我可以使用 this.props.children 完成此操作,如下所示:

class RenderPropComponent extends React.Component {
  const childComponents = React.Children.map(this.props.children, child => {
      return React.cloneElement(child, {ref: node => this.example = node})
  });
  console.log(this.example.test());
  render() {  
    return <div>{childComponents}</div>;
  }
}

...

<RenderPropComponent>
    <Example />
</RenderPropComponent>

但我希望能够使用渲染 Prop 来做到这一点!有什么建议吗?

最佳答案

不完全确定它是否适合您的情况,但也许您可以将 setRef 函数作为参数传递给 render prop?就像这个 fork 的 sandbox .

import React from 'react';
import { render } from 'react-dom';
const styles = {
  fontFamily: 'sans-serif',
  textAlign: 'center',
};

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.setRef = this.setRef.bind(this);
  }
  setRef(node) {
    this.example = node; 
  }
  render() {
    console.log(this.example && this.example.test());
    return this.props.render(this.setRef);
  }
}

class Example extends React.Component {
  test = () => console.log('Test successful!');

  render() {
    return <h1>I am an example!</h1>;
  }
}

const App = () => (
  <div style={styles}>
    <Hello 
      name="CodeSandbox" 
      render={(setRef) => {
        return (
          <Example ref={setRef} />
        )
      }}
    />
    <h2>Start editing to see some magic happen {'\u2728'}</h2>
  </div>
);

render(<App />, document.getElementById('root'));

我在这里看到的唯一问题是,在初始渲染时 this.example 将不可用(这就是为什么我在控制台日志中添加了一个守卫)并且在它被设置之后,将不会触发重新渲染(因为它是在实例上而不是在状态中设置的)。如果需要重新渲染,我们可以将 ref 存储在组件状态中或强制重新渲染。

另一方面,如果您稍后需要在某个事件处理程序中使用 ref,则无需重新渲染即可解决问题。

关于javascript - 无法将 ref 分配给渲染 Prop 中的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48053526/

相关文章:

reactjs - 将 TypeScript 模块从本地模块导入 React 应用程序

reactjs - 使用 ButtonBase 对 Material UI TableRow 产生涟漪效应

JavaScript 可重用函数

javascript - ember-cli 在哪里放置图像

javascript - React.js : Add/Remove input field on click of a button

javascript - Node 应用程序通过暂停当前执行以交互方式从 react 前端获取用户输入

javascript - PEGjs中的条件语法规则

javascript - 使用 jQuery .hide() 和 CSS 媒体查询基于屏幕分辨率进行菜单切换

javascript - 参数 `gte` 的值无效 : input contains invalid characters. 需要 ISO-8601 日期时间。 (棱镜)

javascript - 使用 find() 在对象中循环数组