我试图从数组中筛选一个对象(redux reducer),
const data = [
{id: 0, name: 'Printed Men black Shirt', itemCode: 1000, price: 530, currency: '$', manufacturer: 'ColorWorld'},
{id: 1, name: 'Denim blue white shorts', itemCode: 1001, price: 230, currency: '$', manufacturer: 'ColorWorld'},
{id: 2, name: 'Solid Men blue pants', itemCode: 1003, price: 1530, currency: '$', manufacturer: 'Mecrono Hipli'},
{id: 3, name: 'Checkerd Men Blue Shorts', itemCode: 1300, price: 2530, currency: '$', manufacturer: 'Mecrono Hipli Mini'},
{id: 4, name: 'Self Designed Pant', itemCode: 1056, price: 130, currency: '$', manufacturer:
];
export const listProducts = (state = data, action) => {
switch(action.type){
case LIST_ALL_PRODUCTS: {
return state;
}
case SEARCH_PRODUCT: {
return state.filter((e)=> e.name.includes(action.payload))
}
default:
return state
}
}
这个减速器总是更新实际状态。 为什么这不是一个新的过滤数组?
您可以通过将状态数据结构转换为对象并在redux状态下维护单独的属性来解决问题,例如FilteredData
。
像这样
const initialState = {
data: [
{
id: 0,
name: 'Printed Men black Shirt',
itemCode: 1000,
price: 530,
currency: '$',
manufacturer: 'ColorWorld',
},
{
id: 4,
name: 'Self Designed Pant',
itemCode: 1056,
price: 130,
currency: '$',
manufacturer: '',
},
],
filteredData: [],
}
export const listProducts = (state = initialState, action) => {
switch (action.type) {
case LIST_ALL_PRODUCTS: {
return state
}
case SEARCH_PRODUCT: {
return { ...state, filteredData: state.data.filter((e) => e.name.includes(action.payload)) }
}
default:
return state
}
}
另一种选择
在redux中使用单一数据源,并在组件本身中执行过滤逻辑。 如果有用,请参阅此处的示例演示。
正如我在评论中提到的,您也可以单独存储过滤器本身,并且不在reducer中,而是在组件中进行过滤:
减速器示例:
export const listProducts = (state = data, action) => {
switch (action.type) {
default:
return state;
}
};
export const productNameFilter = (state = "", action) => {
switch (action.type) {
case SEARCH_PRODUCT: {
return action.payload;
}
default:
return state;
}
};
// assuming root reducer is:
// combineReducers({ listProducts, productNameFilter })
在productNameFilter还原程序中,search_product
操作的有效负载应包含产品名称筛选器。 重置搜索筛选器就像将状态设置为“
一样简单。
示例组件,使用挂钩:
const ProductList = () => {
const products = useSelector((state) => state.listProducts);
const productFilter = useSelector((state) => state.productNameFilter);
const shownProducts = products.filter((product) =>
product.name.toLowerCase().includes(productFilter.toLowerCase())
);
return (
<ul>
{shownProducts.map((p) => (
<p key={p.id}>{p.name}</p>
))}
</ul>
);
};
或使用connect
:
const ProductList = ({ products, productFilter }) => {
const shownProducts = products.filter((product) =>
product.name.toLowerCase().includes(productFilter.toLowerCase())
);
return (
<ul>
{shownProducts.map((p) => (
<p key={p.id}>{p.name}</p>
))}
</ul>
);
};
export default connect(ProductList)((state) => ({
products: state.listProducts,
productFilter: state.productNameFilter,
}));