React中子组件的数据是通过props传下去的,但是总是为空



 var Mine = React.createClass({
    getInitialState:function(){
        return {userInfo:[]};
    },
    componentWillMount:function(){

        var _this = this;

        loadCommentsFromServer(apiurl,{
            action:'user_info',
            token:'5b18469422232e5022de1d1c35aa43c1'
        }, function(data) {
            if(data.error_code == 0){
                //console.log(data.data)
                _this.setState({
                    userInfo: data.data
                });

            }else{
                alert('错误代码:' + data.error_code + ',请联系管理员!');
            }
        });
    },
    render:function(){
        return (
            <div id="Mine">
                <Header />

                <MineInfo data={this.state.userInfo} />

            </div>
        );
    }
});

var MineInfo = React.createClass({
    getInitialState:function(){
        console.log(this.props.data)
        return {imgurl:this.props.data.avator,avatorurl:this.props.data.avator,data:this.props.data};
    },

    render:function(){

        var avatarStyle = {
            backgroundImage:'url('+this.state.avatorurl+')'
        }
        return (
            <div id="MineInfo">
                <header id="detailHeadgr">
                    <div className="row">
                        <div className="back col-4"><i className="anticon anticon-left"></i> 返回</div>
                        <div className="title col-16">修改个人信息</div>
                    </div>
                </header>

                <div id="MineInfoAvator">
                    <div className="row-flex row-flex-space-around row-flex-middle">
                        <div className="col-4 avator" style={avatarStyle}></div>
                        <div className="col-15 col-offset-1">更换头像</div>
                        <div className="col-4 arright"><i className="anticon anticon-right"></i></div>
                    </div>
                    <input type="file" accept="image/*" id="uploadAvatar" name="upload" onChange={this.handleFile} />
                </div>


            </div>
        );
    }
});

代码如上面所示。
因为MineInfo 的数据是依赖this.state.userInfo的,但是MineInfo 那里总是获取的数据是空的,然而在Mine 的componentWillMount的时候,更新了userInfo,MineInfo得到的却不是这个更新后的值。

这个应该怎么办呢?

reactjs JavaScript

嗶哩哩嗶哩 9 years, 6 months ago

你的 MineInfo 里是怎么获取 data 的?是下面这种方式么?


 var userInfo = this.props.data;

如果是,那不应该是空啊。

贴一下你的 MineInfo 实现吧

纯洁的板子 answered 9 years, 6 months ago

先说下几个问题

this指向


 var _this = this;

可以改成下面的写法

loadCommentsFromServer(apiurl,{
    action:'user_info',
    token:'5b18469422232e5022de1d1c35aa43c1'
}, function(data) {
    if(data.error_code == 0){
        //console.log(data.data)
        this.setState({
            userInfo: data.data
        });

    }else{
        alert('错误代码:' + data.error_code + ',请联系管理员!');
    }
}.bind(this));

加载数据

从服务端获取数据要放在componentDidMount方法中,官方文档上明确说明了。
clipboard.png

官方文档
中文文档

代码不全

上下文代码不全。

补充


 var Mine = React.createClass({
    getInitialState: function () {
        return {userInfo: {}};
    },
    componentDidMount: function () {
        loadCommentsFromServer(apiurl, {
            action: 'user_info',
            token: '5b18469422232e5022de1d1c35aa43c1'
        }, function (data) {
            if (data.error_code == 0) {
                //console.log(data.data)
                this.setState({
                    userInfo: data.data
                });
            } else {
                alert('错误代码:' + data.error_code + ',请联系管理员!');
            }
        }.bind(this));
    },
    render: function () {
        return (
            <div id="Mine">
                <Header />
                <MineInfo data={this.state.userInfo}/>
            </div>
        );
    }
});

var MineInfo = React.createClass({
    render: function () {
        var avatarStyle = {
            backgroundImage: 'url(' + this.props.data.avatorurl + ')'
        };
        return (
            <div id="MineInfo">
                <header id="detailHeadgr">
                    <div className="row">
                        <div className="back col-4"><i className="anticon anticon-left"></i> 返回</div>
                        <div className="title col-16">修改个人信息</div>
                    </div>
                </header>

                <div id="MineInfoAvator">
                    <div className="row-flex row-flex-space-around row-flex-middle">
                        <div className="col-4 avator" style={avatarStyle}></div>
                        <div className="col-15 col-offset-1">更换头像</div>
                        <div className="col-4 arright"><i className="anticon anticon-right"></i></div>
                    </div>
                    <input type="file" accept="image/*" id="uploadAvatar" name="upload" onChange={this.handleFile}/>
                </div>
            </div>
        );
    }
});

补充


 function loadCommentsFromServer(url, data, callback) {
    setTimeout(function () {
        callback({username: 'xxx', age: 10});
    }, 10);
}

var App = React.createClass({
    getInitialState: function () {
        return {data: {}};
    },
    handleSubmit: function (model) {
        console.log(model);
        //TODO
    },
    componentDidMount: function () {
        loadCommentsFromServer('url', {
            action: 'user_info',
            token: '5b18469422232e5022de1d1c35aa43c1'
        }, function (data) {
            this.setState({
                data: data
            });
        }.bind(this));
    },
    render: function () {
        return (
            <div>
                <Form data={this.state.data} submit={this.handleSubmit}/>
            </div>
        );
    }
});

var Form = React.createClass({
    handleSubmit: function (e) {
        e.preventDefault();
        this.props.submit({
            username: this.refs.username.getDOMNode().value,
            age: this.refs.age.getDOMNode().value
        });
    },
    render: function () {
        return (
            <form onSubmit={this.handleSubmit}>
                <Input type="text" placeholder="Username" value={this.props.data.username} ref="username"/>
                <Input type="text" placeholder="Age" value={this.props.data.age} ref="age"/>
                <button type="submit">submit</button>
            </form>
        );
    }
});


var Input = React.createClass({
    getInitialState: function () {
        return {value: ''};
    },
    componentWillReceiveProps: function (nextProps) {
        this.setState({value: nextProps.value});
    },
    handleChange: function (e) {
        this.setState({
            value: e.currentTarget.value
        });
    },
    render: function () {
        return <input {...this.props} value={this.state.value} onChange={this.handleChange}/>;
    }
});


React.render(<App />, document.body);

771122 answered 9 years, 6 months ago

Your Answer