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 Doc から:

キーは、どの項目が変更、追加、または削除されたかを React が識別するのに役立ちます。配列内の要素にキーを指定して、要素に安定した ID を与える必要があります。レンダリングされたアイテムの安定した ID がない場合は、アイテム インデックスをキーとして使用できます。配列内で使用されるキーは、兄弟間で一意である必要があります。ただし、グローバルに一意である必要はありません。2 つの異なる配列を生成するときに、同じキーを使用できます。

この問題を解決する 1 つの方法は、配列内のアイテムのインデックスを使用することです。そのキーは常に一意になります。これを試して:

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 に答える