0

我的 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");
        });
    }

我想在组件安装后获取新的数据副本。可能这就是我收到此错误的原因。有没有更好的方法?

4

1 回答 1

1

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

来自 Facebook React 文档

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

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

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>
    //);
}
于 2017-01-23T06:19:05.483 回答