Javascript 如何在不影响实际状态的情况下过滤reducer中的数组对象

Javascript 如何在不影响实际状态的情况下过滤reducer中的数组对象,javascript,arrays,reactjs,redux,Javascript,Arrays,Reactjs,Redux,我试图从数组中筛选对象(redux reducer) 此减速器始终更新实际状态。为什么不创建新的筛选数组?您可以通过将状态数据结构转换为对象并在redux状态中维护一个单独的属性来解决问题,例如Filteredata 像这样 const initialState={ 数据:[ { id:0, 姓名:“印花男式黑衬衫”, 项目代码:1000, 价格:530, 货币:“$”, 制造商:“色彩世界”, }, { id:4, 名称:“自行设计的裤子”, 项目代码:1056, 价格:130, 货币:“$”

我试图从数组中筛选对象(redux reducer)


此减速器始终更新实际状态。为什么不创建新的筛选数组?

您可以通过将状态数据结构转换为对象并在redux状态中维护一个单独的属性来解决问题,例如
Filteredata

像这样

const initialState={
数据:[
{
id:0,
姓名:“印花男式黑衬衫”,
项目代码:1000,
价格:530,
货币:“$”,
制造商:“色彩世界”,
},
{
id:4,
名称:“自行设计的裤子”,
项目代码:1056,
价格:130,
货币:“$”,
制造商:“”,
},
],
过滤器数据:[],
}
导出常量listProducts=(状态=初始状态,操作)=>{
开关(动作类型){
所有产品的案例列表:{
返回状态
}
案例搜索产品:{
返回{…state,filteredData:state.data.filter((e)=>e.name.includes(action.payload))}
}
违约:
返回状态
}
}
另一种选择


在redux中使用单一数据源,并在组件本身中执行过滤逻辑。如果有帮助。

您可以通过将状态数据结构转换为对象并在redux状态中维护一个单独的属性来解决问题,例如
Filteredata

像这样

const initialState={
数据:[
{
id:0,
姓名:“印花男式黑衬衫”,
项目代码:1000,
价格:530,
货币:“$”,
制造商:“色彩世界”,
},
{
id:4,
名称:“自行设计的裤子”,
项目代码:1056,
价格:130,
货币:“$”,
制造商:“”,
},
],
过滤器数据:[],
}
导出常量listProducts=(状态=初始状态,操作)=>{
开关(动作类型){
所有产品的案例列表:{
返回状态
}
案例搜索产品:{
返回{…state,filteredData:state.data.filter((e)=>e.name.includes(action.payload))}
}
违约:
返回状态
}
}
另一种选择


在redux中使用单一数据源,并在组件本身中执行过滤逻辑。如果有帮助的话。

正如我在评论中提到的,您还可以单独存储过滤器本身,并且不在减速器中进行过滤,而是在组件中进行过滤:

减速器示例:

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.toLowerCase();
    }
    default:
      return state;
  }
};

// assuming root reducer is:
// combineReducers({ listProducts, productNameFilter })
在productNameFilter reducer中,
搜索\u产品
操作的负载应包含产品名称筛选器。重置搜索筛选器与将状态设置为
''
一样简单

使用钩子的示例组件:

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>
  );
};

正如我在评论中提到的,您还可以单独存储过滤器本身,而不是在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.toLowerCase();
    }
    default:
      return state;
  }
};

// assuming root reducer is:
// combineReducers({ listProducts, productNameFilter })
在productNameFilter reducer中,
搜索\u产品
操作的负载应包含产品名称筛选器。重置搜索筛选器与将状态设置为
''
一样简单

使用钩子的示例组件:

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>
  );
};

这个代码没有问题。请显示动作创建者,您在哪里调用它,以及您在组件中使用状态的位置,这会使您相信它不会更新。@cbr如何使用排列运算符进行复制?请澄清您的问题
.filter
创建一个新数组,它不会改变旧数组。“始终更新实际状态”和“不生成新的筛选数组”是什么意思?@cbr一旦搜索产品案例成功,调用LIST\u ALL\u PRODUCTS案例时,它将返回一个empy数组。此代码没有问题。请显示动作创建者,您在哪里调用它,以及您在组件中使用状态的位置,这会使您相信它不会更新。@cbr如何使用排列运算符进行复制?请澄清您的问题
.filter
创建一个新数组,它不会改变旧数组。“始终更新实际状态”和“不创建新的筛选数组”是什么意思?@cbr一旦搜索产品案例起作用,在调用LIST\u ALL\u PRODUCTS案例时,它会返回一个empy数组。当然,我甚至建议只存储筛选器本身并在组件中执行它。@cbt这也很好,您能告诉我如何在组件中执行此操作吗?请查看答案中提到的演示链接…它有完整的示例代码:)当然,我甚至建议只存储过滤器本身并在组件中执行。@cbt这也很好,你能告诉我如何在组件中实现它吗?请查看答案中提到的演示链接…它有完整的示例代码:)