ReactJS中初始状态的未定义值

Undefined value for initial state in ReactJS

本文关键字:未定义 初始状态 ReactJS      更新时间:2023-09-26

我对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_nderTypeError:this.props.files.map不是函数。(在this.props.files.map中,this.props.files.map未定义)

如果我的<Modal>组件中的console.log(this.state.data.files),它也表明this.state.data.files是未定义的?显然,我还不明白发生了什么。我也尝试过用componentWillMount获取数据,但这也没有帮助。我做错了什么?

谢谢!


更新

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

有什么想法吗?

是的,它当然会抛出错误,因为你正在传递这个<L5fmModalBody files={this.state.data.files} />和你的状态,它在data : []中声明,这意味着当第一次渲染发生时,数据只是一个空数组,你的组件在浏览器上渲染一次,然后调用L5fmModal的componentDidMount,它将从DB中获取数据,并再次更新状态和渲染函数,调用数据file字段,但当您的数组当时为空时,第一次加载该怎么办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}

感谢达瓦尔·帕特尔,我终于找到了这个问题的答案。问题不在于初始状态的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}

在CCD_ 19分量中。