首页 > 解决方案 > 为什么列表消失并且过滤不起作用?

问题描述

我向服务器发出请求并获取我在视图表列表中显示的数据(类别列表)并实现一些功能
我有一个任务,我应该如何处理列表:

按标题名称过滤我可以使用查询参数来实现,当用户在输入中写入一些类别并按下按钮提交时q,我将其插入到文件apiCategory.js
中 Example: http://path/q=animals
在这种情况下,页面上只会显示类别动物。

但是当我编写实现按title name列表过滤的代码时,就消失了。并且过滤不起作用

在代码中修复什么?

也许我在方法中写错了,filter或者updateSearchInput

主页.js:

const Home = () => {
  const [value, setValue] = useState({
    listCategory: [],
    filteredlistCategory: [],
    searchInput: ""
  });
   
  useEffect(() => {
    async function fetchData( searchInput ) {
        const res = await apiCategory('/pathApi', {
          method: 'GET',
        }, searchInput);
        
          setValue(prev => ({
            ...prev,
            listCategory: res.data,
         }));
    }
    fetchData(value.searchInput); 
  }, [value.searchInput]);


    const updateSearchInput = (e) => {
       setValue((prev) => ({
         searchInput: e.target.value
       }));
     };

    const filter = () => {
       setValue((prev) => 
          ({ searchInput, listCategory}) => ({
          filteredlistCategory: listCategory.filter(item =>
          item.firstName.toLowerCase().includes(searchInput.toLowerCase()))
     }))
    };
  
  return (
    <div>
       <Search value={value.searchInput} onChange={updateSearchInput} onSearch={filter}/>  
       <Table dataAttribute={value.filteredlistCategory}/>
    </div>
  );
};

apiCategory.js:

export const apiCategory = async (url, args, valueFilter) => {
  const response = await fetch(`${url}?q=${valueFilter}`, {   
   ...args,
    headers: {/....}
    }});

 return response.json();      
}

搜索.js:

export default ({ value, onChange, onSearch }) => {
  return (
    <div className="search">
        <input type="text" className="searchInput" onChange={onChange} value={value}/>
        <button className="buttonSearch" onClick={() => onSearch(value)}>Search</button>
    </div>
  );
};

来自服务器的响应:

{"data":[           
          {"id":1,"title":"animals","created_at":"/...","updated_at":"/..."},
          {"id":2,"title":"space","created_at":"/...","updated_at":"/..."},
          {"id":3,"title":"sport","created_at":"/...","updated_at":"/..."}
        ]
}

标签: reactjs

解决方案


我可以看到代码的一些问题:

  1. 在您的fetchData函数中,您没有设置filteredlistCategory,而是将此列表传递给Table组件,因此最初不会显示任何数据,因为列表是空的。
  2. updateSearchInput你没有保留旧值(listCategoryfilteredlistCategory)。这可能就是列表消失的原因。它应该更像这样:
const updateSearchInput = (e) => {
    const searchInput = e.target.value;
    setValue((prev) => ({
        ...prev,
        searchInput: searchInput
    }));
};
  1. 过滤功能不正确,它包含提供给的双重功能setValue,您需要去掉其中一个。目前,您基本上是将函数设置为状态值,这会导致过滤不起作用。尝试这样的事情:
const filter = () => {
    setValue((prev) => ({
        ...prev
        filteredlistCategory: listCategory.filter(item =>
            item.firstName.toLowerCase().includes(searchInput.toLowerCase())
        )
    }))
};

但是,在这种情况下,为了代码的清晰,我建议为每个属性创建单独的状态(3 useStates 而不是 1),因此您不需要记住在仅更改其中一个时保留其他人的旧值他们。或者,尝试使用useReducer钩子。

编辑:我对您的 Home.js 文件进行了一些更改,应该可以解决这些问题:

  • 在对输入到搜索输入中的每个字符发出新的 API 请求之前 - 这是低效的,我已将其更改为仅在filter单击按钮后发出请求。它是通过从 中删除依赖关系来完成的useEffect,因此它只在初始组件创建时运行一次,并在filter函数中发出请求。
  • 删除filteredlistCategory了属性,因为似乎没有必要在此组件内存储重复列表(数据总是从新搜索的服务器中获取)
const Home = () => {
    const [value, setValue] = useState({
        listCategory: [],
        searchInput: ""
    });

    useEffect(() => {
        fetchData(value.searchInput);
    }, []);

    const fetchData = async ( searchInput ) => {
        const res = await apiCategory('/pathApi', {
            method: 'GET',
        }, searchInput);

        setValue(prev => ({
            ...prev,
            listCategory: res.data
        }));
    }

    const updateSearchInput = (e) => {
        const searchInput = e.target.value;
        setValue((prev) => ({
            ...prev,
            searchInput: searchInput
        }));
    };

    const filter = async () => {
        await fetchData(value.searchInput);
    };

    return (
      <div>
          <Search value={value.searchInput} onChange={updateSearchInput} onSearch={filter}/>
          <Table dataAttribute={value.listCategory}/>
      </div>
    );
};

推荐阅读