警告:flattenChildren(...):在React Mobx组件中遇到两个具有相同键的子节点

时间:2017-01-23 05:23:58

标签: reactjs mobx mobx-react

我在MobX React组件中收到此错误:

Warning: flattenChildren(...): Encountered two children with the same key, `1:$8`. Child keys must be unique; when two children share a key, only the first child will be used.

如果我是第一次加载此路由,则不会显示此错误消息。

这是我的整个组成部分:

@observer
export default class Posts extends React.Component {

    componentDidMount(){
        this.props.route.posts.getPosts();
    }

    hiren() {
        var bunny = [];
        (this.props.route.posts.posts).map(function (data) {
            bunny.push(
                <div className="post-preview" key={ data.id }>
                    <Link to={'/dashboard/posts/' + data.id + '/'}>
                        <h2 className="post-title">
                            {data.title}
                        </h2>
                    </Link>
                    <p className="post-meta">Posted on {data.date}</p>
                </div>
            )
        });
        return (
            <div> {bunny} </div>
        );
    }

    render() {

        if(this.props.route.posts.loaded){
            return (
                <div className="posts">
                    <div className="container">
                        <div className="row">
                            <div className="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">

                                {this.hiren()}
                            </div>
                        </div>
                    </div>

                </div>
            )
        }
        return (

            <div>
                <h3>{this.props.route.posts.loadingText} </h3>
            </div>
        )

    }
}

这是我的mobx商店:

export class Diary {
    @observable loaded = false;
    @observable searching = false;
    @observable posts = [];
    @observable post = {} ;
    @observable loadingText = 'Loading from remote server....';
    @observable pageId = 0;

    @action getPosts() {
        axios({
            method: 'get',
            url: '/api/diary/',
            headers: {'Authorization': "JWT " + sessionStorage.getItem('token')}
        }).then(action('response action', (response) => {
            this.loadingText = 'Decrypting data...';
            (response.data).map(function (post) {
                let key = forge.pkcs5.pbkdf2(sessionStorage.getItem('key'),
                    forge.util.hexToBytes(post['salt']), 100, 16);
                let hiren = {};
                hiren['id'] = post['id'];
                hiren['title'] = Crypt.decrypt(post['title'], key, post['iv']);
                hiren['content'] = Crypt.decrypt(post['content'], key, post['iv']);
                hiren['tag'] = post['tag'];
                hiren['date'] = moment.utc(post['date']).local().format("dddd, DD MMMM YYYY hh:mm:ss A");
                this.posts.push(hiren);
            }.bind(this));
            this.loaded = true;
        })).catch(function(err) {
            console.error(err);
            sweetAlert("Oops!", err.statusText, "error");
        });
    }

我希望在组件安装后获得新的数据副本。也许这就是我收到此错误的原因。有没有更好的方法?

1 个答案:

答案 0 :(得分:1)

您习惯来的错误,当您为多个元素分配相同的密钥时,动态创建的元素需要唯一的密钥。

From Facebook React Doc

  

键帮助React识别哪些项目已更改,已添加或已删除。应该为数组内部的元素赋予键,以使元素具有稳定的标识。如果渲染项目没有稳定的ID,则可以使用项目索引作为键。数组中使用的键在其兄弟姐妹中应该是唯一的。但是,它们不需要是全球唯一的。当我们生成两个不同的数组时,我们可以使用相同的键。

解决此问题的一种方法是,使用数组中item的索引,该键始终是唯一的。试试这个:

hiren() {
    //var bunny = [];
    return this.props.route.posts.posts.map((data, index) => {
        return(
            <div className="post-preview" key={ index }>
                <Link to={'/dashboard/posts/' + data.id + '/'}>
                    <h2 className="post-title">
                        {data.title}
                    </h2>
                </Link>
                <p className="post-meta">Posted on {data.date}</p>
            </div>
        )
    });
    //return (
    //    <div> {bunny} </div>
    //);
}