我有两个组件来演示我的问题:
父级:
import React from "react";
import ReactDOM from "react-dom";
import { Grid, Row } from "react-flexbox-grid";
import Hello from "./Hello";
class App extends React.Component {
state = {
name: "Michal"
};
componentDidMount = () => {
this.setState({ name: "Tina" });
};
componentDidUpdate(prevState) {
console.log("App componentDidUpdate", prevState, this.state);
}
handleUpdate = value => {
console.log("App handleUpdate");
this.setState({ name: value });
};
render() {
return (
<Grid>
<Row>
<Hello name={this.state.name} update={this.handleUpdate} />
</Row>
</Grid>
);
}
}
ReactDOM.render(<App />, document.getElementById("container"));孩子:
import * as React from "react";
class Hello extends React.PureComponent {
componentDidMount() {
// setTimeout(() => {
this.props.update("Matus");
// }, 0);
}
componentDidUpdate(prevProps) {
console.log("Hello componentDidUpdate", prevProps, this.props);
}
render() {
return <h1>Hello {this.props.name}!</h1>;
}
}
export default Hello;在子组件中,我希望通过props函数设置父状态中的值。但是props函数被忽略,如果从setTimeout调用setState函数,它就会起作用。
你能给我解释一下为什么它在setTimeout中工作,为什么我应该避免这种构造吗?那么正确的方法是什么呢?
Hello组件代表“选择”,在componentDidMount中它将获取选项并设置默认值。
谢谢。
发布于 2020-07-23 05:10:50
组件在React中自下而上进行初始化。因此,在您的示例中,Hello触发componentDidMount,尝试通过this.props.update在应用程序中设置状态,然后App在调用自己的componentDidMount时瞬间覆盖它。您在子组件中设置的名称永远不会到达该状态。
我不确定这是什么目的,希望只是为了学习的目的,因为组件不应该在挂载时立即设置自己的状态。如果您需要在初始化App中的状态之前执行一些逻辑,您可以使用constructor并在那里执行。
无论如何,解决方案是删除App中的初始状态设置器。
发布于 2020-07-23 05:09:53
它不会被忽略,它确实会触发。你只是没有用你的日志来观察它。查看:
https://codesandbox.io/s/kind-jackson-b2r2b?file=/src/App.js
在控制台中,您将在控制台窗口中看到以下执行顺序:
Hello componentDidMount props = Object {name: "Michal", update: function ()}
App handleUpdate value = Matus
App componentDidMount props = Object {}
Hello componentDidUpdate props = Object {name: "Tina", update: function ()}
App componentDidUpdate state = Object {}
Object {name: "Tina"}因此,您将看到子componentDidMount在父组件完成之前启动并完成挂载,并在组件从子组件向上完成挂载时启动其componentDidMount。
所以你永远不会观察到Matus的状态,因为它会在Tina完成挂载时触发一个新的状态更改。
发布于 2020-07-23 05:18:24
由于React生命周期的原因,来自Hello组件的setState函数被忽略。基本上,App componentDidMount函数会在Hello组件呈现之前覆盖它的状态更改。这就是setTimeout提供帮助的原因,它将您的状态更改移动到新的呈现循环。
我不知道您为什么要加载数据并将其从子组件传递到父组件,但React中的良好实践是从上到下传递数据。因此,更好的解决方案是使用Select组件来呈现来自父对象的数据,并对用户事件做出反应。
<Select options={options} selected={option} handle={handleSelect} />https://stackoverflow.com/questions/63042824
复制相似问题