父状态更改后,React子组件不会更新

时间:2016-12-20 01:10:34

标签: reactjs

我试图制作一个漂亮的ApiWrapper组件来填充各种子组件中的数据。从我读过的所有内容中,这应该有效:https://jsfiddle.net/vinniejames/m1mesp6z/1/

#banner {
background:url('.png');
width:100%;  
height:100%; <!--- ? --->
background-size:100%;
background-repeat: no-repeat;
margin-left: auto;
margin-right: auto;
}

但由于某种原因,当父状态发生变化时,似乎子组件没有更新。

我在这里错过了什么吗?

3 个答案:

答案 0 :(得分:139)

您的代码存在两个问题。

您的子组件的初始状态是根据道具设置的。

this.state = {
  data: props.data
};

引用此SO Answer

  

将初始状态作为prop传递给组件是一种反模式   因为getInitialState(在我们的例子中是constuctor)方法只是第一次调用   组件渲染。从来没有。这意味着,如果你重新渲染它   组件将不同的值作为prop传递给组件   不会做出相应的反应,因为组件会保持状态   从第一次渲染。这很容易出错。

因此,如果您无法避免这种情况,理想的解决方案是使用方法componentWillReceiveProps来监听新的道具。

将以下代码添加到子组件将解决Child组件重新呈现的问题。

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

第二个问题是fetch

_makeApiCall(endpoint) {
  fetch(endpoint)
    .then((response) => response.json())   // ----> you missed this part
    .then((response) => this.setState({ response }));
}

这是一个工作小提琴:https://jsfiddle.net/o8b04mLy/

答案 1 :(得分:5)

如果上述解决方案仍然没有解决您的问题,我建议您查看一下您是如何更改状态的,如果您没有返回新对象,那么有时 react 会发现新的前一个和更改的对象没有区别状态,在改变状态时总是传递一个新对象是一个很好的做法,看到新对象反应肯定会重新渲染所有需要访问改变状态的组件。

例如:-

在这里,我将更改我状态中一组对象的一个​​属性,看看我如何将所有数据分散到一个新对象中。另外,下面的代码对你来说可能有点陌生,它是一个 redux reducer 函数,但别担心它只是一个改变状态的方法。

export const addItemToCart = (cartItems,cartItemToBeAdded) => {
        return cartItems.map(item => {
            if(item.id===existingItem.id){
                ++item.quantity;        
            }
            // I can simply return item but instead I spread the item and return a new object
            return {...item} 
        })
    } 

只要确保您正在使用新对象更改状态,即使您对状态进行了微小的更改,只需将其分散到一个新对象中然后返回,这将在所有适当的位置触发渲染。 希望这有帮助。如果我在某个地方错了,请告诉我:)

答案 2 :(得分:0)

有些事情你需要改变。

fetch得到回复时,它不是json。 我一直在寻找如何获得这个json,我发现了这个link

另一方面,您需要认为constructor函数只被调用一次。

因此,您需要更改在<Child>组件中检索数据的方式。

在这里,我留下了一个示例代码:https://jsfiddle.net/emq1ztqj/

我希望有所帮助。