最近看来,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 })
传递函数作为prop,根据最新的React 16.9,猜猜this.props.children
不是函数。
作为使用GraphQL的人们的参考,我看到Apollo客户的<Mutation>
和<Query>
的工作方式大致相同。
如何实现?
编辑:为什么不重复?
因为其他答案依赖this.props.children
作为函数,而最近React现在却呈现错误,要求针对此问题采取新的方法:
TypeError:this.props.children不是函数
答案 0 :(得分:2)
我已经回答了必要的更新,以显示问题所在以及如何在下面的行内进行更改。
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具有kindly pointed out,您可以传递this.props.children(this.close)
而不是对象,但是我发现它更易于阅读/使用。
您可以分叉并尝试或运行下面的代码片段〜
感谢Emile Bergeron在the comment的建议〜
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>
答案 1 :(得分:0)
尝试这个
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(this.close) }
</div>
)
}
}