这是我试过的一小段代码:
var CommentBox = React.createClass({
loadCommentsFromServer: function () {
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'GET',
success: function (data) {
this.setState({data: data});
}.bind(this),
error: function (xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this),
cache: false
});
},
getInitialState: function () {
return {data: []};
},
componentDidMount: function () {
this.loadCommentsFromServer();
},
render: function () {
return (
<div className="commentBox">
<MessageBox1 data={this.state.data}/>
</div>
);
}
});
var MessageBox1 = React.createClass({
getInitialState: function() {
alert('MessageBox1 getInitialState');
return {nameWithQualifier: 'Mr. ' + this.props.data.pageName};
},
componentDidMount: function() {
alert('this.props.data: ' + this.props.data);
},
render: function() {
return (<div>
<div>{this.state.nameWithQualifier}</div>
<div> {this.props.data.pageName}</div>
</div>
);
}
});
ReactDOM.render(<CommentBox url="/save/6"/>, document.getElementById('content'));
在 CommentBox 中,我正在查询 ID 为 6 的对象并将其传递给 MessageBox1 组件。我想让这个对象成为 MessageBox1 组件中的状态变量。这里的问题是,我无法读取 props 变量。 “this.props.data”在 MessageBox1 组件的 getInitialState 和 ComponentDidMount 中未定义。然而,在渲染函数中我可以看到正确的值。我已经尝试了几个示例,在这些示例中我能够读取 getInitialState 中的 Prop 数据。为什么这不在这里发生?请帮忙。我在控制台中没有任何错误。
最佳答案
我相信您对 React 组件生命周期有些困惑。
我建议快速阅读本文以了解何时调用每个生命周期方法。 http://busypeoples.github.io/post/react-component-lifecycle/
在您的 getInitialState 方法中的 messagebox1 中,像这样初始化您的状态结构,以防止在 Prop 可用之前访问它们。
{ nameWithQualifier: '' }
您正在调用异步操作来获取数据,因此无法保证何时检索数据。但是,根据您现在拥有它的方式(在 componentDidMount 上),它将始终在 messageBox1 初始化后被检索,这解释了为什么 this.props.data 在 getInitialState 中未定义。我建议在 componentWillMount 中触发 loadCommentsFromServer 以尽早触发异步操作,并且可以在组件安装之前设置状态。
与其在 setInitialState 中设置 messageBox1 的状态,不如尝试像这样使用 componentWillReceiveProps。它将保证您的状态在 props 更改时更新。
componentWillReceiveProps(newProps) {
this.setState({ nameWithQualifier: 'Mr. ' + newProps.data.pageName })
}
但是,如果在这个嵌套的 messageBox1 组件呈现之前异步数据偶然可用,您可能还想在 messageBox1 上执行此操作以确保状态在初始呈现时是最新的:
componentWillMount() {
this.setState({ nameWithQualifier: 'Mr. ' + this.props.data.pageName })
}
所以如果你真的想这样做,我推荐上面的2条建议
- 在 componentWillMount 中调用您的 ajax 请求,以便更早发送请求
- 在 componentWillReceiveProps 的子组件中更新您的状态(每次 Prop 更新时都会更新您的状态)
然而,在大多数情况下,似乎没有必要使用 props 设置组件状态。也许尝试这样的事情:
在 commentBox 组件的渲染函数中将 pageName 作为 prop 向下发送:
render: function () {
return (
<div className="commentBox">
<MessageBox1 pageName={this.state.data.pageName}/>
</div>
);
}
在 messageBox 渲染函数中,您可以通过直接访问 Prop 来简化流程。它会给你相同的结果。
render: function() {
return (<div>
<div>{'Mr. ' + this.props.pageName}</div>
<div> {this.props.pageName}</div>
</div>
);
}
这将适用于这种简单的情况,除非您出于某种原因需要更改 messageBox1 中的 Prop ,因为 Prop 对于它们所在的组件是不可变的。它们只会在父组件更改向下传递的内容时更新。
关于javascript - 无法在reactjs的子组件中读取getInitialState和ComponentDidMount中的 Prop 数据对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37106664/