javascript - 无法在reactjs的子组件中读取getInitialState和ComponentDidMount中的 Prop 数据对象

标签 javascript jquery reactjs

这是我试过的一小段代码:

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条建议

  1. 在 componentWillMount 中调用您的 ajax 请求,以便更早发送请求
  2. 在 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/

相关文章:

javascript - 删除一行 Bootstrap Table

javascript - 使用 sql 输出创建动态 JSON

javascript - 居中图像并从中心调整大小。无余量

reactjs - create-react-app 如何在构建过程中将特定的 .ts 文件编译为 .js 文件?

javascript - 使用 Jest 测试 React Native 时如何模拟 LayoutAnimation

javascript - 处理 React 中的 localStorage 更改以重新渲染组件

jquery - Div 相互重叠

javascript - 选定的选项从 php 中的数据库获取数据

javascript - 何时使用 attrs 与直接通过样式组件传递 props ?

javascript - React - 动态表单字段,其中字段根据下拉菜单更改(使用 Hook )