ReactJS中初始状态的未定义值

时间:2015-12-30 11:09:18

标签: javascript reactjs

我仍然对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'未定义)

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

谢谢!

更新

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

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

是的,当然它会抛出错误,因为你传递了这个data : []和你在componentDidMount声明的状态,这意味着当第一次渲染时数据只是一个空白数组和你的组件完成后,在您的浏览器上呈现,然后调用L5fmModal 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} 使用

//get package name of current running application.
ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
packageName = mActivityManager.getRunningAppProcesses().get(1).processName;

答案 1 :(得分:1)

感谢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}

<Modal />组件中。

相关问题