我试图制作一个漂亮的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;
}
但由于某种原因,当父状态发生变化时,似乎子组件没有更新。
我在这里错过了什么吗?
答案 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/
我希望有所帮助。