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

Warning: flattenChildren(...): Encountered two children with the same key in React Mobx Component

我在我的 MobX React 组件中遇到这个错误:

Warning: flattenChildren(...): Encountered two children with the same key, `1:`. 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");
        });
    }

我想在组件 mounting.May 之后获取新的数据副本,这就是我收到此错误的原因。有没有更好的方法?

你习惯了的错误,当你为许多元素分配相同的键时,动态创建的元素需要唯一键。

From Facebook React Doc:

Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity. When you don't have stable IDs for rendered items, you may use the item index as a key. Keys used within arrays should be unique among their siblings. However they don't need to be globally unique. We can use the same keys when we produce two different arrays.

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

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>
    //);
}