【问题标题】:How to rewrite state correctly in filters React如何在过滤器 React 中正确重写状态
【发布时间】:2021-10-12 21:12:22
【问题描述】:

我需要在 React 中使用输入过滤器。我有一个活动列表,需要像图片上的过滤器一样过滤它们。如果未选中图标,则不应显示具有这些类型活动的操作。它有效。

当我使用输入过滤器并写信时它工作的问题。但是当我一个字母一个字母地删除时,什么都没有改变。

我知道问题是我在状态中写了结果。并且状态发生了变化。但是如何正确地重写它。

const [activities, setActivities] = useState(allActivities);
  const [value, setValue] = useState(1);
  const [checked, setChecked] = useState<string[]>([]);

  const switchType = (event: React.ChangeEvent<HTMLInputElement>)=> {
    const currentIndex = checked.indexOf(event.target.value);
    const newChecked = [...checked];

    if (currentIndex === -1) {
      newChecked.push(event.target.value);
    } else {
      newChecked.splice(currentIndex, 1);
    }

//function that shows activities if they are checked or unchecked
    
setChecked(newChecked);

    const res = allActivities.filter(({ type }) => !newChecked.includes(type));
    setActivities(res);
  };
//shows input filter
  const inputSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
    
    const foundItems = activities.filter(
      (item) => item.activity.indexOf(event.target.value) > -1
    );

    setActivities(foundItems);
  };
//shows participants filter
  const countSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
    setValue(Number(event.target.value));
    const participantsSearch = allActivities.filter(
      (item) => item.participants >= event.target.value
    );
    setActivities(participantsSearch);
  };

这是渲染部分

  <Input
            onChange={inputSearch}       
               startAdornment={
              <InputAdornment position="start">
                <SearchIcon />
              </InputAdornment>
            }
          />
 <Input
            onChange={countSearch}
            type="number"
            value={props.value}
                      startAdornment={
              <InputAdornment
                position="start"
                className={classes.participantsTextField}
              >
                <PersonIcon />
              </InputAdornment>
            }
          />

【问题讨论】:

    标签: reactjs filter state


    【解决方案1】:

    这里的问题是您保存了正在过滤的状态,因此每次应用过滤器时,数据只能减小大小或保持不变.它永远无法重置为完整的、未经过滤的数据。

    此外,由于您编写复选框和输入回调的方式,您无法轻松地将两者混用。

    由于过滤后的数据本质上是从allActivities 属性以及valuechecked 状态“派生”的状态,因此它确实不应该也存储在状态中。渲染时可以内联过滤allActivities

    const [value, setValue] = useState<sting>('');
    const [checked, setChecked] = useState<string[]>([]);
    
    const switchType = (event: React.ChangeEvent<HTMLInputElement>)=> {
      const currentIndex = checked.indexOf(event.target.value);
    
      if (currentIndex === -1) {
        setChecked(checked => [...checked, event.target.value]);
      } else {
        setChecked(checked => checked.filter((el, i) => i !== currentIndex);
      }
    };
    
    const inputSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
      setValue(event.target.value.toLowerCase());
    };
    
    ...
    
    return (
      ...
    
      {allActivites.filter(({ activity, type }) => {
          if (activity || type) {
            if (type) {
              return checked.includes(type);
            }
            if (activity) {
              return activity.toLowerCase().includes(value);
            }
          }
          return true; // return all
        })
        .map(.....
    

    【讨论】:

      【解决方案2】:

      问题在于您的inputSearch 代码。 每次您执行setActivities(foundItems); 时,您都会缩小activities 列表的状态。因此,当您开始删除时,您看不到任何更改,因为您从状态中删除了其余活动。

      您需要将allActivities 取出到一个常量中,并始终在inputSearch 中过滤allActivities,如下所示:

      const allActivities = ['aero', 'aeroba', 'aerona', 'aeronau'];
      const [activities, setActivities] = useState(allActivities);
      
      // ...rest of your code
      
      const inputSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
        const foundItems = allActivities.filter(
          (item) => item.activity.indexOf(event.target.value) > -1
        );
        setActivities(foundItems);
      };
      // ...rest of your code
      

      【讨论】:

      • 我同意这个变体,但是在这个变体中我们过滤了所有的活动。我需要过滤在复选框过滤器之后选择的那些。换句话说,所有过滤器都是连接的。如果我选择体育和社交活动,输入过滤器必须显示这种类型的活动,但不是全部。
      猜你喜欢
      • 2020-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 2021-09-15
      • 2016-03-17
      相关资源
      最近更新 更多