首页 > 解决方案 > 将函数传递给 this.props.children

问题描述

似乎最近 React 不会this.props.children像过去那样将其视为函数。

我刚刚编写了一个Modal组件,它的closeModal功能应该传递给孩子,

render() {
  return (
    <Modal>
      {
        (closeModal) => {
          return (<span onClick={closeModal}>Click to close modal</span>)
        }
      }
    </Modal>
  )
}

模态看起来像这样

class Modal extends React.Component {
  constructor(props) {
    this.state = { show: true }

    this.close = this.closeModal.bind(this)
  }

  closeModal() {
    this.setState({ show: false })
  }

  render() {
    if (!this.state.show)
      return null

    return (
      <div>
        { this.props.children }
      </div>
    )
  }
}

我试图通过 将函数作为道具传递this.props.children({ closeModal: this.closeModal }),猜猜看,this.props.children这不是根据最新 React 16.9 的函数。

作为使用 GraphQL 的人的参考,我看到 Apollo 客户端的<Mutation>工作<Query>方式几乎相同。

如何实现?

编辑:为什么不重复?因为其他答案依赖于this.props.children函数,而最近 React 现在正在呈现错误,需要一种新的方法来解决这个问题:TypeError: this.props.children is not a function

标签: javascriptreactjs

解决方案


我已经回答了显示错误以及如何在下面在线更改所需的更新。

class Modal extends React.Component {
  constructor(props) {
    // 1️⃣ Make sure to make `props` available in this component.
    // This call is what makes `this.props` call to be available within `Modal`.
    super(props);

    this.state = { show: true };

    // 2️⃣ Assign a newly bound method to the matching class method
    // this.close = this.closeModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
  }

  closeModal() {
    this.setState({ show: false });
  }

  render() {
    if (!this.state.show) return null;

    // 3️⃣ Pass the modal handler to children
    // If you had kept `this.close`, then when you pass the handler
    // "{ closeModal: this.close }" instead of "{ closeModal: this.closeModal }"
    return <div>{this.props.children({ closeModal: this.closeModal })}</div>;
  }
}

function App() {
  return (
    <div className="App">
      <Modal>
        {/* 4️⃣ destructure `closeModal` */}
        {({ closeModal }) => {
          return <button onClick={closeModal}>Click to close modal</button>;
        }}
      </Modal>
    </div>
  );
}

正如 Emile Bergeron友好地指出的那样,您可以传递this.props.children(this.close)而不是对象,但我发现它更易于阅读/使用。

您可以 fork 并尝试或运行下面的代码片段~
感谢Emile Bergeron在评论中的建议~
编辑 so.answer.57812519

class Modal extends React.Component {
  constructor(props) {
    super(props);

    this.state = { show: true };

    // this.close = this.closeModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
  }

  closeModal() {
    this.setState({ show: false }, () => {
      console.log(`Modal closed`);
    });
  }

  render() {
    if (!this.state.show) return null;

    return <div>{this.props.children({ closeModal: this.closeModal })}</div>;
  }
}

function App() {
  return (
    <div className="App">
      <Modal>
        {({ closeModal }) => {
          return (
            <button type="button" onClick={closeModal}>
              Click to close modal
            </button>
          );
        }}
      </Modal>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>

<div id="root"></div>


推荐阅读