我很擅长使用componentDidMount
和setState
来更新自定义组件,这似乎是推荐的做法。下面是一个示例(包括用于获取数据的axios
API调用):
import React from 'react';
import {MyComponent} from 'my_component';
import axios from 'axios';
export default class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
data: []
};
}
GetData() {
return axios.get('http://localhost:5000/<route>');
}
componentDidMount() {
this.GetData().then(
(resp) => {
this.setState(
{data: resp.data}
)
}
)
}
render() {
return (
<MyComponent data={this.state.data} />
);
}
}
在console.log(this.state.data)
下方render()
显示this.state.data
确实已更新(从[]
到API返回的任何内容)。但是,问题似乎是MyComponent
不会重新呈现componentDidMount
。来自Facebook的反应文档:
在此方法中设置状态将触发重新渲染。
这似乎不是这样的:MyComponent
的构造函数只被调用一次(其中this.props.data = []
)并且组件不会再次渲染。如果有人可以解释为什么会这样,以及是否有解决方案或完全不同的方式来完成更新,我会很高兴。
更新
我添加了MyComponent
的代码(减去一些不相关的功能,如...
所示)。 console.log(data_array)
打印一个空数组。
import React from 'react';
class DataWrapper {
constructor(data) {
this._data = data;
}
getSize() {
return this._data.length;
}
...
}
export class MyComponent extends React.Component {
constructor(props) {
super(props);
this._dataWrapper = new DataWrapper(this.props.data);
this.state = {
data_array: this._dataWrapper,
};
}
render() {
var {data_array} = this.state;
console.log(data_array);
return (
...
);
}
}
答案 0 :(得分:4)
您正在成为this antipattern.
的受害者在MyComponent
构造函数中,它只在第一次调用时被调用,通过new DataWrapper
传递空数组,现在你有一些本地状态,无论你的父母做什么都不会更新。
拥有一个真理来源,只需一个状态对象(尤其是像ajax响应之类的东西),并通过道具传递它们总是更好。事实上,你可以将MyComponent
写成一个简单的函数,而不是类。
class Example extends Component {
state = { data: [] }
GetData() { .. }
componentDidMount() {
this.GetData().then(res =>
this.setState({data: new DataWrapper(res.data)})
)
}
render() { return <MyComponent data={this.state.data} /> }
}
...
function MyComponent (props) {
// props.data will update when your parent calls setState
// you can also call DataWrapper here if you need MyComponent specific wrapper
return (
<div>..</div>
)
}
答案 1 :(得分:0)
换句话说,Azium的意思是您需要将接收组件变成受控组件。意思是,它根本不应该有状态。直接使用道具。
是的,甚至将其变成功能组件。这可以帮助您牢记功能组件通常没有状态(可以将状态放入其中,但是...分离关注点)。
如果需要从该受控组件中编辑状态,请通过props提供功能并在“主”组件中定义功能。因此,主组件只是将控制权交给孩子。他们想要与父母交谈的任何内容。
我不在这里发布代码,因为您需要做出的修改可以忽略不计。在受控组件中具有this.state的位置,请更改为this.props。