gpt4 book ai didi

reactjs - 在ReactJs组件中替换状态时如何避免 'children with same key'

转载 作者:行者123 更新时间:2023-12-03 13:00:09 25 4
gpt4 key购买 nike

我创建了一个 React 组件,它根据给定的 id 数组呈现一组子元素。 ids 数组保存在父组件的状态中,然后我根据 ids 运行一些 ajax 调用来获取要渲染的数据。获取的数据存储在状态中的单独数据数组中。渲染的组件使用 id 作为键

ID 可以根据组件外部的操作进行更改,因此我在组件上使用 setState 来替换数组。 更新后的 id-state 可能会包含一些与原始数组中相同的 id。同时,我清空“数据数组”,以便再次渲染所有内容。

当我这样做时,有时会收到关键警告:

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

新数组不包含任何重复项。那么为什么会发生这种情况,我该怎么做才能避免这种情况呢?

编辑:根据请求添加了一些代码。注意:我使用的是Infinite Scroll module 。可能是这个原因造成的?

初始状态:

getInitialState: function() {
return {
hasMore: true,
num: 0,
movieIds: this.props.movieIds,
movies: []
};
},

渲染函数:

render: function() {
var InfiniteScroll = React.addons.InfiniteScroll;

return (
<InfiniteScroll
pageStart={0}
loadMore={this.loadMore}
threshold='20'
hasMore={this.state.hasMore}>
<ul className="movieList">
{this.state.movies}
</ul>
</InfiniteScroll>
);
}

简化加载更多:

comp = this;
$.ajax( {
url: url,
contentType: "json",
success: function (data) {
var m = createMovieLi(data);
var updatedMovies = comp.state.movies;
updatedMovies[num] = m;
comp.setState({movies: updatedMovies});
}
});

最后在组件外部更新时:

movieBox.setState({
hasMore: true,
num: 0,
movieIds: filteredIds,
movies: []
});

最佳答案

我发现了我的错误,它与 React 本身无关。这是missing javascript closure inside a loop的经典案例.

由于可能存在重复,我将每个 ajax 响应存储在 movieId 上的 window.localStorage 中。或者说我是这么想的。

在 React Infinite Scroll 中,列表中的每个项目都是通过调用 loadMore 函数按顺序绘制的。在这个函数中,我执行了 ajax 调用,并将结果存储在浏览器缓存中。代码看起来像这样:

  var cachedValue = window.localStorage.getItem(String(movieId));
var cachedData = cachedValue ? JSON.parse(cachedValue) : cachedValue;

if (cachedData != null) {
comp.drawNextMovie(cachedData);
} else {
$.ajax( {
type: "GET",
url: this.state.movieUrl + movieId,
contentType: "json",
success: function (movieData) {
window.localStorage.setItem(String(movieId), JSON.stringify(movieData));
comp.drawNextMovie(movieData);
}
});
}

你能发现错误吗?当 ajax 调用返回时,movieId 不再是原来的样子。所以我最终用错误的 id 存储了数据,并得到了一些奇怪的 React 警告作为返回。因为这是在 InfiniteScroll 模块调用的 loadMore 函数内完成的,所以我不知道该函数的作用域不正确。

我通过添加 Immediately-invoked function expression 来修复它.

关于reactjs - 在ReactJs组件中替换状态时如何避免 'children with same key',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26088810/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com