我正在尝试制作一个不错的ApiWrapper组件,以填充各种子组件中的数据。从我阅读的所有内容来看,这应该可以正常工作:https : //jsfiddle.net/vinniejames/m1mesp6z/1/
class ApiWrapper extends React.Component { constructor(props) { super(props); this.state = { response: { "title": 'nothing fetched yet' } }; } componentDidMount() { this._makeApiCall(this.props.endpoint); } _makeApiCall(endpoint) { fetch(endpoint).then(function(response) { this.setState({ response: response }); }.bind(this)) } render() { return <Child data = { this.state.response } />; } } class Child extends React.Component { constructor(props) { super(props); this.state = { data: props.data }; } render() { console.log(this.state.data, 'new data'); return ( < span > { this.state.data.title } < /span>); }; } var element = < ApiWrapper endpoint = "https://jsonplaceholder.typicode.com/posts/1" / > ; ReactDOM.render( element, document.getElementById('container') );
但是由于某种原因,当父状态更改时,子组件似乎没有更新。
我在这里想念什么吗?
您的代码有两个问题。
您的子组件的初始状态是通过props设置的。
this.state = { data: props.data };
引用此SO答案:
将初始状态作为a传递给组件prop是一种反模式,因为getInitialState(在我们的示例中为constuctor)方法仅在组件首次呈现时才调用。再也没有了。这意味着,如果重新渲染该组件并传递一个 不同的 值a prop,则该组件将不会做出相应的反应,因为该组件将从首次渲染起就保持该状态。这很容易出错。
prop
getInitialState
因此,如果您无法避免这种情况,理想的解决方案是使用该方法componentWillReceiveProps来侦听新道具。
componentWillReceiveProps
将以下代码添加到子组件将解决子组件重新渲染的问题。
componentWillReceiveProps(nextProps) { this.setState({ data: nextProps.data }); }
第二个问题是fetch。
fetch
_makeApiCall(endpoint) { fetch(endpoint) .then((response) => response.json()) // ----> you missed this part .then((response) => this.setState({ response })); }
这是一个有效的小提琴:https : //jsfiddle.net/o8b04mLy/