[英]Passing state after .setState() to child component but not showing up in this.props for child component
为什么我能够在运行 componentDidMount() 后打印我的 this.state.email 但是当我将状态传递给子组件时我无法在子组件的 this.props.email 中访问它
class HomePage extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
isAuthorized: false,
name: "",
email: "",
};
}
loadGoogleApi() {
...
this.makeApiCall()
...
}
makeApiCall() {
gapi.client.people.people.get({
'resourceName': 'people/me',
'personFields': 'names,emailAddresses',
}).then(resp => {
this.setState({
name: resp.result.names[0].givenName,
email: resp.result.emailAddresses[0].value
});
});
}
componentDidMount() {
this.loadGoogleApi();
}
render() {
return(
<div>
{ !this.state.isAuthorized ? (
<button onClick={ this.handleAuthClick } id="authorize-button">Login/Signup</button>
) : (
<div>
<p>{ "Hello, " + this.state.name + "!" }</p>
<p>{ "Hello, " + this.state.email + "!" }</p>
<Main email={ this.state.email }/>
</div>
) }
</div>
);
}
}
Main.js 组件
class Main extends React.Component {
constructor(props) {
super(props);
this.state = {};
console.log(this.props); // PRINTS ==> {email: ""}
}
render() {
return (
<div> Test </div>
);
}
}
export default Main;
在第一个组件初始化中,它将使用其props
。 但是稍后,如果将其props
设置为this.props = newProps
,则此newProps
将在componentWillReceiveProps
可用。 您可以在这里获取newProps
并执行您想要协助state
任何事情。
另外,您可以在这里参考以了解React的生命周期。
setState()并不总是立即更新组件。 它可能会批量更新或将更新推迟到以后。 这使得在调用setState()之后立即读取this.state可能是一个陷阱。 而是使用componentDidUpdate或setState回调(setState(updater,callback)),确保在应用更新后均能触发这两种方法。 如果需要基于先前的状态来设置状态,请阅读以下有关updater参数的信息。
字体: https : //facebook.github.io/react/docs/react-component.html
React setState是一个异步函数,有时他们批处理您的状态并将其放入队列,在这种情况下,可能是这样的:
尝试console.log componentWillReceiveProps
内部的道具
例如
componentWillReceiveProps(nextProps) {
console.log(nextProps);
}
原因是构造函数在初始渲染时仅被调用一次,然后再调用一次,并且您在Child构造函数中记录了props
值,因此,如果您想在Child中看到更新后的值,则它将始终打印初始props值,将控制台放入渲染器中打印更新的值。
您还可以使用componentWillReceiveProps生命周期方法检查udpated道具值。
在已安装的组件接收新道具之前,将调用componentWillReceiveProps()。
像这样:
class Main extends React.Component {
render() {
//here
console.log(this.props);
return (
<div> Test </div>
);
}
}
您的代码中的问题在于,在HomePage.js
的第一个render调用之后会调用componentDidMount
。 因此,道具在子代中可用,并且由于子代中的构造函数仅被调用一次,因此不会更新道具。 如果要从子项中的props更新状态,或者如果要直接使用它,请在子项组件中使用componentWillReceiveProps
和componentDidMount
,如果要直接在渲染器中使用它
PS确保在孩子中执行未定义的检查
class Main extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
componentWillReceiveProps(nextProps) {
console.log(nextProps);
}
render() {
console.log(this.props.email);
return (
<div> Test </div>
);
}
}
export default Main;
您可以通过 componentWillReceiveProps 方法简单地刷新子组件 (Main.js) 的状态,如下所示。
class Main extends React.Component {
constructor(props) {
super(props);
this.state = { data: this.props.dataParentToChild }; // Initial data set
console.log(this.props); // PRINTS ==> {email: ""}
}
componentWillReceiveProps(nextProps) {
this.setState({ data: this.nextProps.dataParentToChild }); // Refresh data
console.log(this.nextProps); // PRINTS ==> {email: "updated value"}
}
render() {
return (
<div> Test </div>
);
}
}
export default Main;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.