javascript - React Parent Component 的 this.state 在 Child Component 的构造函数之后被调用
问题描述
我在反应中遇到了一些违反直觉的行为(至少对我而言)。我有一个 API 调用,它返回一些要显示的 JSON。我希望此调用的结果处于父组件(“问题容器”)的状态,并作为道具传递给其子组件(“问题”)。
我在子组件中得到了一个未定义的结果,所以我在 4 个不同的地方进行了一些控制台日志记录,以查看发生了什么:在每个构造函数中一次,在每个组件“this.state”中使用我的“getProblemsFromAPI()”函数一次.
父组件:
class ProblemContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
problem_set: getProblemsFromAPI()
};
{console.log(this.state.problem_set, 'parent constructor')}
}
render() {
return(
<div>
<Problem problem_set={this.problem_set} />
</div>
)
}
}
function getProblemsFromAPI(problem_set = {}) {
fetch("http://localhost:5000/api/problem_set/5")
.then(response => response.json())
.then((data) => {console.log(data, 'set state of parent'); return data});
}
子组件:
class Problem extends React.Component {
constructor(props){
super(props);
this.state = {
current_problem: '',
problem_set: getProblemsFromAPI()
}
console.log(this.props, 'child constructor')
}
render() {
return (
<div>
</div>
);
}
}
function getProblemsFromAPI(problem_set = {}) {
fetch("http://localhost:5000/api/problem_set/5")
.then(response => response.json())
.then((data) => {console.log(data, 'set state of child'); return data});
}
我在控制台中看到的是:
- “父构造器”
- “儿童建造师”
- “设置父状态”
- “设置孩子的状态”
这对我来说很奇怪,因为父组件的“this.state”构造函数应该是顺序调用的第一件事。我可以将 API 调用放在子组件的 componentDidMount 中继续前进,这不是问题。我只是不明白这种行为。
这是因为它是一个函数调用而不是一个值吗?我对 javascript 和反应都很陌生。任何建议都会有所帮助!
谢谢
解决方案
任何副作用,例如从外部 API 获取数据或任何状态变量更新,都应该在组件安装在componentDidMount
生命周期方法(如果使用类组件)或useEffect
挂钩(如果使用功能组件)之后完成。既然您说您希望将ProblemContainer
数据传递给它的孩子。ProblemContainer
应该负责获取数据。
例如,
class ProblemContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
problem_set: null,
error: undefined
};
}
componentDidMount() {
fetch("http://localhost:5000/api/problem_set/5")
.then(response => response.json())
.then((data) => {this.setState({problem_set: data})});
// never leave a promise with out catching the error
.catch(error => {
// you can console.log the error to see what is going wrong
this.setState({problem_set: null, error: error})
})
}
render() {
return(
<div>
<Problem problem_set={this.state.problem_set} /> // you need to pass the prop like this
</div>
)
}
}
在您的问题组件中,
class Problem extends React.Component {
// you have access to the problem_set via this.props.problem_set
render() {
console.log(this.props.problem_set) // should show the expected result
return (
<div>
// component logic
</div>
);
}
}
推荐阅读
- excel - 仅将过滤结果复制到同一工作表但不同的列
- c# - 添加嵌入对象时如何隐藏 AddOLEObject [C#]
- node.js - MERN Stack - 使用 API 删除项目
- java - 如何在 webview 中接收通知?
- ruby - URI.escape 的简单替代方案
- node.js - 将node-js的net模块与adonis集成
- r - 如何计算R中数据框中提到的列表中的单词数
- sqlite - Xamarin,我如何访问 sqlite 中的特定列属性以便添加值?
- php - 将 .min($prices) 格式化为逗号分隔
- google-cloud-platform - Google 云端硬盘同意页面消息