【问题标题】:Undefined value for initial state in ReactJSReactJS 中初始状态的未定义值
【发布时间】:2016-04-04 08:35:01
【问题描述】:

我对 ReactJS 还是很陌生,现在我遇到了一些让我完全困惑的事情。

我创建了一堆呈现 Bootstrap 模式的组件。此外,我通过componentDidMount 函数从服务器获取初始状态参数。我的组件结构如下所示:

<App>
  <Modal Lauch Button /> 

  <Modal>
   <Modal Header />
   <Modal Body />     <-- here's the problem
  </Modal>
</App>

而我的初始状态数组的形式是(当然是 JSON 编码的):

array:5 [▼
   ...
   ...
   "private" => true
   "files" => array:2 [▼
       1 => array:7 [▼
          "id" => 0
          "route" => "some route"
          ...
          ...
       ]
       2 => array:7 [▼
          "id" => 1
          "route" => "some other route"
          ...
          ...
       ]
   ]
]

和我的(缩小的)React 应用程序是这样的:

<script type="text/babel">

    var L5fmModalBody = React.createClass({

        render: function() {

            return(
                <Modal.Body>
                    <Grid fluid={true}>
                        <Row>
                            {
                                this.props.files.map(function (file) {
                                    return <L5fmModalBodyFileContent id={file.id} route = {file.route} / >
                                })
                            }
                        </Row>
                    </Grid>
                </Modal.Body>
            );
        }

    });

    var L5fmModalBodyFileContent = React.createClass({

        render : function() {
            return(
                <Col xs={6} md={4} className="img-row">
                    <div className="thumbnail thumbnail-img">
                        <img key={this.props.id} src={this.props.route} />
                    </div>
                </Col>
            );
        }

    });

    var L5fmModal = React.createClass({

        getInitialState : function() {
            return {
                data : []
            };
        },

        componentDidMount: function() {
            $.ajax({
                url: 'L5fm/setInitialState',
                dataType: 'json',
                cache: false,
                success: function(data) {
                    this.setState({data: data});
                    console.log(data);
                    console.log(this.state.data);
                }.bind(this),
                error: function(xhr, status, err) {
                    console.error(this.props.url, status, err.toString());
                }.bind(this)
            });
        },

        render: function() {

            return(

                <Modal {...this.props} bsSize="large" aria-labelledby="contained-modal-title-lg">
                    <Modal.Header closeButton>
                        <div className="header-button-group">
                            some buttons
                        </div>
                    </Modal.Header>

                    <L5fmModalBody files={this.state.data.files} />
                </Modal>
            );
        }

    });


    var App = React.createClass({
        getInitialState: function() {
            return { lgShow: false };
        },
        render: function() {
            let lgClose = () => this.setState({ lgShow: false });

            return (
                 <Button bsStyle="primary" onClick={()=>this.setState({ lgShow: true })}>
                    Launch large demo modal
                 </Button>
                 <L5fmModal show={this.state.lgShow} onHide={lgClose} />
            );
        }
    });

    ReactDOM.render(<App />, document.getElementById("modal"));

</script>

每当我运行应用程序时,我都会收到以下错误:

L5fmModalBody_renderTypeError:this.props.files.map 不是函数。 (在'this.props.files.map'中,'this.props.files.map'未定义)

如果我在我的&lt;Modal&gt; 组件中console.log(this.state.data.files),它还表明this.state.data.files 未定义?显然我还没有明白发生了什么。我也尝试使用componentWillMount 获取数据,但这也无济于事。我做错了什么?

谢谢!


更新

我想我更进一步了。实际的问题不是 this.set,state 一开始就是 null,因为在调用 componentDidMount 并设置了“新”状态后,UI 会再次呈现。此外,我发现 JSON 显然将关联数组作为对象处理,我相信我不能在对象上调用 map

有什么想法吗?

【问题讨论】:

  • this.state.data 记录了什么?
  • 如果我将console.log(this.state.data) 放入&lt;L5fmModal&gt; 的渲染函数中,我会得到[] (0) 作为日志输出。我猜这只是预定义的空 data 数组。但是如何从服务器获取数据然后渲染整个应用程序呢?
  • @FlorianRagossnig:不需要那样做,因为第一次它只会渲染 UI,然后一旦 API 成功函数调用 API,你已经再次设置了状态,所以它会再次调用你的渲染函数,现在你有数据,所以它会用数据填充 UI

标签: javascript reactjs


【解决方案1】:

是的,当然它会抛出错误,因为你传递了这个 &lt;L5fmModalBody files={this.state.data.files} /&gt; 并且你的状态是在 data : [] 中声明的,这意味着当第一次渲染发生时,数据只是一个空白数组,一旦完成,你的组件就会在浏览器上渲染你的 L5fmModal 的 componentDidMount 被调用,它将从数据库中获取数据并再次更新状态和渲染函数调用并且数据有一个 file 字段但是当你的数组只是一个空的时候第一次加载呢time file 字段未定义,因此您必须在 L5fmModalBody

中实现以下提到的代码
     {
(type of this.props.files != 'undefined')? this.props.files.map(function (file) {
                                        return <L5fmModalBodyFileContent id={file.id} route = {file.route} / >
                                    }):null                                
}

或者你也可以防止你的L5fmModal它自己使用

{this.state.data.length>0 ? <L5fmModalBody files={this.state.data.files} />:null}

【讨论】:

  • 嗨,达瓦尔!感谢您的回复。不幸的是,这个解决方案不起作用。模态被渲染但没有正文内容。
  • @FlorianRagossnig:这意味着您的数据始终为空,请检查您的 API 调用
  • 我是这么认为的,我想我现在更进一步了。我意识到我的返回“数组”实际上不是一个数组而是一个对象,我相信我不能在对象上使用map。您对这个问题有什么建议吗?
  • @FlorianRagossnig:是的,你可以使用 Object.keys(data).map(function(d){return });
【解决方案2】:

感谢Dhaval Patel 我终于有了这个问题的答案。问题不在于初始状态的null 值,因为当componentDidMount 被调用时,UI 会再次呈现并从服务器接收更新的状态。实际问题是 JSON 将关联数组视为对象,因此我无法调用简单的 map

我只是换了

{
    this.props.files.map(function (file) {
        return <L5fmModalBodyFileContent id={file.id} route = {file.route} / >
    })
}

{
    Object.keys(object).map(
        function(d){
            return <L5fmModalBodyFileContent id={object[d].id} route={object[d].route} />
    })
}

object = this.props.files 就像一个魅力!

为了避免我使用的(起初)未定义对象的错误

{this.state.data.length!=0 ? <L5fmModalBody files={this.state.data.files} />:null}

&lt;Modal /&gt; 组件中。

【讨论】:

    猜你喜欢
    • 2018-08-03
    • 2018-08-22
    • 2019-06-22
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多