在更新父状态时,似乎不会呈现React子组件?

时间:2016-01-28 09:58:06

标签: ajax reactjs

我有一个(可能是愚蠢的)关于反应工作流程的问题,我显然还没有完全理解。

我有一个父组件,它通过ajax调用从服务器获取数据。其中一个返回值是一个布尔值,它作为属性传递给子组件。然而,子组件再次根据属性值从服务器(ajax)获取数据。不知何故,父组件相应地做了更改,但是孩子没有重新渲染?我做错了什么?

父组件:

var L5fmModal = React.createClass({

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

        componentDidMount: function() {
            this.loadItems('L5fm/setState', null);
        },

        loadItems : function(url, modalState) {
            $.ajax({
                url: url,
                contentType: 'application/json; charset=UTF-8',
                data: {modalState : JSON.stringify(modalState)},
                dataType: 'json',
                cache: false,
                success: function(data) {
                    this.setState({data: data, initRunSwitch: true});
                    console.log(this.state.data);
                }.bind(this),
                error: function(xhr, status, err) {
                    console.error(url, status, err.toString());
                }.bind(this)
            });
        },

        changeListView : function() {
            if (this.state.data.listView) {
                var newData = update(this.state.data, { listView: { $set: false }  });
            }
            else {
                var newData = update(this.state.data, { listView: { $set: true } });
            }
            this.loadItems('L5fm/setState',newData);
        },

        changeDirectory : function() {
            if (this.state.data.dirState.private) {
                var newData = update(this.state.data, {dirState : { private: { $set: false } } });
            }
            else {
                var newData = update(this.state.data, {dirState : { private: { $set: true } } });
            }
            this.loadItems('L5fm/setState',newData);
        },


        render: function() {

            if (this.state.initRunSwitch) {
                if(this.state.data.dirState.private) {
                    var browseIcon = "glyphicon-folder-open";
                    var browseText = "browse all files";
                }
                else {
                    console.log('undefined here');
                    var browseIcon = "glyphicon-briefcase";
                    var browseText = "browse private files";
                }

                if (this.state.data.listView) {
                    var listIcon = "glyphicon-picture";
                    var listText = "image View";
                }
                else {
                    var listIcon = "glyphicon-list";
                    var listText = "list View";
                }
            }

            return(

                <Modal {...this.props} bsSize="large" aria-labelledby="contained-modal-title-lg">
                    <Modal.Header closeButton>
                        <div className="header-button-group">
                            <L5fmHeaderButton buttonIcon="glyphicon-cloud-upload" buttonText="upload" />
                            <L5fmHeaderButton onClick={this.changeListView} buttonIcon={listIcon} buttonText={listText} />
                            <L5fmHeaderButton onClick={this.changeDirectory} buttonIcon={browseIcon} buttonText={browseText} />
                        </div>
                    </Modal.Header>

                    {this.state.initRunSwitch ? <L5fmModalBody dirState={this.state.data.dirState} listView={this.state.data.listView} />:null}
                </Modal>
            );
        }

    });

子组件():

var L5fmModalBody = React.createClass({

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

        componentDidMount: function() {
            this.loadFiles('L5fm/setModalBodyState', this.props.dirState);
        },

        loadFiles : function(url, dirState) {
            $.ajax({
                url: url,
                contentType: 'application/json; charset=UTF-8',
                data: {dirState : JSON.stringify(dirState)},
                dataType: 'json',
                cache: false,
                success: function(data) {
                    this.setState({files: data});
                }.bind(this),
                error: function(xhr, status, err) {
                    console.error(url, status, err.toString());
                }.bind(this)
            });
        },

        render: function() {

            var object = this.state.files;

            return(
                <Modal.Body>
                    <Grid fluid={true}>
                        <Row>
                            {this.props.listView ? <L5fmModalBodyListView fileObject={object} /> : <L5fmModalBodyImageView fileObject={object} />}
                        </Row>
                    </Grid>
                </Modal.Body>
            );
        }

    });

1 个答案:

答案 0 :(得分:1)

componentDidMount仅在初始渲染(docs)上运行。您应该对componentWillReceiveProps中的后续 prop 更改做出反应。