为什么我在运行componentDidMount()之后能够打印my.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;
答案 0 :(得分:2)
在第一个组件初始化中,它将采用其props
。但是稍后如果您将props
设置为this.props = newProps
,则此newProps
将在componentWillReceiveProps
中提供。你可以在这里抓住newProps
并做任何你想做的事情,比如分配给state
。
此外,您可以参考here查看React生命周期。
答案 1 :(得分:1)
setState()并不总是立即更新组件。有可能 批量或推迟更新,直到稍后。这使得阅读this.state 在调用setState()之后发生了潜在的陷阱。相反,使用 componentDidUpdate或setState回调(setState(更新程序, 回调)),其中任何一个都保证在更新后触发 已经应用。如果需要根据以前的状态设置状态 state,请阅读下面的updater参数。
字体:https://facebook.github.io/react/docs/react-component.html
React setState是一个异步函数,有时它们批量你的状态并将它放在队列中,在这种情况下可能发生这种情况:
尝试在componentWillReceiveProps
e.g。
componentWillReceiveProps(nextProps) {
console.log(nextProps);
}
答案 2 :(得分:1)
原因是 constructor 在初始渲染后只调用一次,而不是在那之后,您在Child构造函数中记录props
值,因此它将始终打印初始道具值如果你想在Child中看到更新的值将控制台放在渲染中,它将打印更新的值。
您还可以使用componentWillReceiveProps生命周期方法检查udpated道具值。
在安装的组件之前调用componentWillReceiveProps() 收到新的道具。
像这样:
class Main extends React.Component {
render() {
//here
console.log(this.props);
return (
<div> Test </div>
);
}
}
答案 3 :(得分:1)
代码中的问题是componentDidMount
在HomePage.js
中的第一次渲染调用之后被调用。因此,孩子可以使用道具,因为孩子中的构造函数只被调用一次,所以道具不会更新。如果要从子项中的props更新状态,或者如果您想直接使用它,则需要在子组件中使用componentWillReceiveProps
和componentDidMount
,在渲染中使用它
P.S。确保在孩子中执行未定义的检查
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;