【问题标题】:componentWillReceiveProps not firingcomponentWillReceiveProps 未触发
【发布时间】:2017-03-12 13:32:34
【问题描述】:

在我的其他课程中,componentWillReceiveProps 运行良好,但由于某种原因,它没有在这里触发。

ItemView.jsx

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

        this.state = {
            name: null, 
            rating: null, 
            sector: null, 
            location: null, 
            description: null, 
            image: "blank.png",
            show: false
       };
    }

    ...

    componentWillReceiveProps(nextProps) {

        if(!nextProps.companyToRender) {
            this.setState({
                name: null, 
                rating: null, 
                sector: null, 
                location: null, 
                description: null, 
                image: "blank.png",
                show: false
            });
       }
       else {
           var companyToRender = nextProps.companyToRender;

           this.setState({
               name: companyToRender.name, 
               rating: companyToRender.rating, 
               sector: companyToRender.sector, 
               location: companyToRender.location, 
               description: companyToRender.description, 
               image: companyToRender.image,
               show: true
           });
    }

    ...

    render () {
       return(
        <div>
         ...
        <CommentBox show={this.state.show} companyToRender={this.state.name}/>
         ...
        </div>
       );

    }
}

评论框.jsx

class CommentBox extends React.Component {
    constructor(props) {
        super(props);
        this.state = {companyToRender: null};
    }

    componentWillReceiveProps(nextProps) {
        this.setState({companyToRender: nextProps.companyToRender});
    }

    ...
}

如果不传递任何内容,则传递给 itemView 的 prop 为 null,或者 ItemView 分配给它的数组。

componentWillReceiveProps() 仅在状态的属性变为 null 时触发,而不是在设置时触发。 ( (null --> entry) 不起作用,但 (entry --> null) 起作用)。

我错过了什么吗?谢谢!

-- 编辑:

(null --> entry) 更新状态,但不调用日志或任何后续 componentWillRecieveProps()。 (但 entry --> null 可以。)

Logs for null --> entry

Logs for entry --> null

【问题讨论】:

  • 您是否在ItemViewcomponentWillReceiveProps 或通过chrome 的react 检查器插件验证name 状态设置正确?听起来`ItemView` 没有重新渲染,因为name 没有改变。
  • 我尝试在 componentWillReceiveProps() 函数和 CommentBox.jsx 的 render() 函数中记录。奇怪的是,它并没有打印出 componentWilRecieveProps() 中的日志,而是在 null-->entry 期间更改了 render() 中的状态。我将更新条目以在 chrome 上显示输出。
  • "如果不传递任何内容,传递给 itemView 的 prop 要么为 null,要么为 ItemView 分配给它的数组。"这只是您的问题中的一个错误,还是 companyToRender 是一个数组(如您所说)?我想它应该是一个对象。另外,请注意 componentWillReceiveProps 在组件首次安装时不会被调用(但仅在之后)。

标签: reactjs react-jsx


【解决方案1】:

经过痛苦的调试,我发现问题在于 ItemView 在模态(react-bootstrap)中被调用,由于某种原因,它不支持 componentWillReceiveProps()。最后通过重构代码解决了这个问题。谢谢大家!

【讨论】:

  • 您是否在网上某处找到了对此的确认或提交了错误?
  • 这很有意义!由于 Modal 必须在每次发生更改时创建一个全新的组件,因此永远不会调用 componentWillReceiveProps(它只应该在有 new 道具时调用,而不是初始道具)。尝试将您的道具逻辑放在constructor() 中!另外,ty 为我节省了大量的调试时间。
  • 感谢您跟进并发布问题所在!我刚刚在使用 react-modal 创建的模态组件中遇到了同样的事情,您的回答很快就提醒了我这个问题。
  • 我遇到了不同库的模态并将代码放入构造函数中使其工作。谢谢@JamesM.Lay
【解决方案2】:

我也有同样的问题。如果有人输入了直接 url,则 componentwillreceiveprops 不会触发。我还必须重构我的代码以使其全部正常工作。

我所做的更改是在我最初的 index.tsx 中具有类似的内容(即,将路由器作为外部元素):

render( 
<Router history={hashHistory} >
{routes}
</Router>
, document.getElementById('root'));

我的默认路由是到我的 app.tsx 页面,其结构如下: 渲染() {

return (
 <Provider store={store}>
   <div id="appContainer">
           {this.props.children}
   </div>
 </Provider>
);

}

【讨论】:

    【解决方案3】:

    如果其他人对此有疑问...

    componentWillReceiveProps不会被调用,如果你收到 exact same 与以前一样的道具。你可以做些什么来解决它是添加一个虚拟道具,每次你想向组件发送相同的道具时都会迭代,以防组件内部以某种方式重置自己

    click() {
        this.setState({counter: ++this.state.counter, unchangingProp:true})
    }
    <Component unchangingProp={this.state.unChangingProp} counter={this.state.counter}/>
    

    这样componentWillRecieveProps每次都会被触发。

    【讨论】:

    • 不知何故更新组件状态也不会触发componentWillReceiveProps
    • @JohhanSantana 这是 React 生命周期中的有意行为,您可以参考 this picture 了解发生了什么。
    • 我觉得这很混乱,可能会导致用户选择错误的架构和反模式。我建议查看考虑模式和反模式的 React 文档。例如这个页面:reactjs.org/blog/2018/06/07/…
    • 这是一种快速而肮脏的方法。如果您有更好的解决方案,请发布并投票支持
    【解决方案4】:

    在我的情况下,每次渲染都会重新创建我的组件,因此我必须将我的逻辑放入构造函数中。我知道它并不理想,但它是一个简单的组件,并且比尝试解决导致每次重新创建组件的问题对我来说更容易做到。

    【讨论】:

    • 如果您必须将逻辑放入构造函数中,请尝试使用 componentDidMount。它应该与构造函数同时触发。
    猜你喜欢
    • 2018-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多