我在反应中遇到了一些违反直觉的行为(至少对我而言)。我有一个API调用,返回一些要显示的JSON。我希望此调用的结果处于父组件(“问题容器”)的状态,并作为道具传递给其子组件(“问题”)。
我在子组件中得到了未定义的结果,所以我在4个不同的位置进行了一些控制台日志记录,以查看发生了什么:在每个构造函数中一次,在每个组件中一次使用“ get.ProblemsFromAPI()在“ this.state”中“功能。
父组件:
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>
);
}
}