【发布时间】:2017-04-03 16:07:03
【问题描述】:
我正在尝试解决我在 ui 中呈现来自我创建的 es6 类的项目列表时看到的问题。该模型运行良好,但是我正在使用正在侦听(反应)项目的 mount、onEnter 和 onLeave 的动画。
当我通过模型应用过滤器和排序并通过 getter 返回新的项目列表时,动画不适用于某些项目,因为列表只是重新排序,不一定会更改。
所以我的 getter 只是抓取类的 this.products 并将其返回并对其应用排序顺序。如果应用了过滤器(由类中的this._checkedList 跟踪),this.products 会根据选择然后排序的过滤器来减少。所以那个吸气剂看起来像这样:
get productList() {
if (this._checkedList.length > 0) {
const filteredProducts = _.reduce(this.filterMap, reduceFilters, []);
const deDuped = _.uniq(filteredProducts, 'id');
return this.applySort(deDuped);
}
const deDuped = _.uniq(this.products, 'id');
return this.applySort(deDuped);
}
我想弄清楚的是一种在过滤器或排序运行时临时发回空数组的方法。原因是 ui 会收到一个空数组(即使是一瞬间),并且 react 会将新的排序/过滤列表注册为新列表并再次触发进入/离开/安装动画。
我的尝试是设置类的本地属性,例如 -
this._tempReturn = false;
然后在排序或过滤发生的函数中,我将其设置为 true,然后在函数完成后返回 false -
toggleFilter(args) {
this._tempReturn = true;
...toggle logic
this._tempReturn = false;
}
然后在我做任何其他事情之前更改 getter 以检查该属性,如果它是真的,发回一个空数组 -
get productList() {
if (this._tempReturn) {
return [];
}
...
}
但是,这似乎不起作用。即使将 console.log 放入 if (this._tempReturn) { 也没有显示任何日志。
我还尝试用 lodash 的_.cloneDeep 发回一个新列表,如下所示:
get productList() {
if (this._checkedList.length > 0) {
const filteredProducts = _.reduce(this.filterMap, reduceFilters, []);
const deDuped = _.uniq(filteredProducts, 'id');
return _.cloneDeep(this.applySort(deDuped));
}
const deDuped = _.uniq(this.products, 'id');
return _.cloneDeep(this.applySort(deDuped));
}
这也不起作用。所以看起来空数组返回可能是一个更好的方法。
我想知道是否有某种方法可以实现这一点 - 我希望数组在过滤器和排序应用时返回空一秒钟。
非常坚持如何实现,也许我什至从错误的角度看待这个问题,并且有更好的方法来解决这个问题。欢迎任何建议,感谢阅读!
【问题讨论】:
-
您需要渲染视图两次——一次使用空数组,另一次使用数据。那是一个异步组件,可以通过事件、回调或承诺来实现。但是,根据您的 React 实现,实现会有所不同。例如,如果使用 redux,你可能会有两个动作——比如
GET_ARRAY_START和GET_ARRAY_COMPLETE,你会在开始时使用空数组加载存储,在完成时加载实际数据。无论您选择哪种方法,您还需要一种方法来告诉 React,一旦数据准备就绪,就该重新渲染了 -
您不应该需要将列表呈现为空然后排序以使其正确呈现更改。听起来您只需要确保您的项目具有唯一的关键属性。改变孩子的关键属性总是会让 react 重新渲染孩子。
-
@MikeDriver 就是这样!不检查我觉得很傻,我使用索引作为键。如果您想添加答案,我将标记为正确。谢谢!!
-
@ajmajmajma 会的,很高兴能提供帮助!
标签: javascript reactjs ecmascript-6