【发布时间】:2016-03-24 20:24:06
【问题描述】:
我构建了一个列表,其中包括一个搜索表单,用于在 React.js 中使用 Redux 按关键字过滤列表。
这是控制器组件的一部分:
const mapStateToProps = (state) => {
// make a sorted array of the keys in the items object
var sortedItems = Object.keys(state.items).sort(function(a, b) {
if(state.items[a].name.toLowerCase() < state.items[b].name.toLowerCase()) return -1;
if(state.items[a].name.toLowerCase() > state.items[b].name.toLowerCase()) return 1;
return 0;
});
// apply the filter to this array
sortedItems = filterByKeyword(sortedItems, state.items, state.filter.keyword);
return {
items: state.items,
sortedItems
}
}
这是过滤器:
export const filterByKeyword = function(sortedItems, items, keyword) {
keyword = keyword.toLowerCase();
return sortedItems.filter(function(id) {
return items[id].name.toLowerCase().indexOf(keyword) !== -1;
});
}
这是列表组件:
const ItemList = ({ items, sortedItems }) => (
<div>
{Object.keys(sortedItems).map(function(key) {
var id = sortedItems[key];
return (
<div key={id}>
{items[id].name}
</div>
);
}, this)}
</div>
);
基本上这是可行的,但是一旦更改关键字,我就会收到如下错误:
Uncaught Invariant Violation: findComponentRoot(..., .0.1.0.0.$123): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG-elements in an <svg> parent. Try inspecting the child nodes of the element with React ID ``.
我还制作了一个版本,其中过滤后的项目保存在第二个数组中,而 ItemList 迭代所有项目,如果在过滤后的项目数组中找不到 id,则将 className='hide' 分配给 div。虽然这可以正常工作,但速度太慢了。
那么,过滤这样的列表的正确 React/Redux 方法是什么?
【问题讨论】:
-
这里显示的代码似乎与错误消息无关。你是否在 React 之外以某种方式操作 DOM?例如用 jQuery?
-
不,都是 React。不涉及 jQuery。