Javascript 使用useEffect时超出最大深度
我正在尝试为我的产品CRUD实现一个简单的搜索算法。 我的想法是在搜索栏中输入输入,每次用户更改输入时,匹配搜索的产品都会立即出现,而无需点击搜索按钮。 然而,我试着这样做:Javascript 使用useEffect时超出最大深度,javascript,reactjs,Javascript,Reactjs,我正在尝试为我的产品CRUD实现一个简单的搜索算法。 我的想法是在搜索栏中输入输入,每次用户更改输入时,匹配搜索的产品都会立即出现,而无需点击搜索按钮。 然而,我试着这样做: function filterProducts (productName, productList) { const queryProducts = productList.filter((prod)=> { return prod.title === productName; }); retur
function filterProducts (productName, productList) {
const queryProducts = productList.filter((prod)=> {
return prod.title === productName;
});
return queryProducts;
}
function HomePage () {
const [productList, setProductList] = useState([]);
const [popupTrigger, setPopupTrigger] = useState('');
const [productDeleteId, setProductDeleteId] = useState('');
const [queryString, setQueryString] = useState('');
let history = useHistory();
useEffect(() => {
if (queryString.trim() === "") {
Axios.get("http://localhost:3001/api/product/get-all").then((data) => {
setProductList(data.data);
});
return;
}
const queryProducts = filterProducts(queryString, productList);
setProductList(queryProducts);
}, [queryString, productList]);
我知道productList
会更改每个渲染,这可能就是它不起作用的原因。但我不知道如何解决这个问题。我在这里看到了useReducer的其他问题和解决方案,但我觉得它们似乎都没有帮助我。
错误如下所示:
警告:超过最大更新深度。当组件在useEffect内部调用setState时,可能会发生这种情况,但useEffect没有依赖项数组,或者每个渲染中的一个依赖项都会更改。当您在useEffect挂钩中使用setState函数,同时将该setState函数的状态作为useEffect挂钩的依赖项之一时,您将获得这种递归效果,最终无限地重新渲染组件 因此,首先我们必须从useEffect中删除productList。然后,我们可以使用一个函数来更新您的状态,而不是陈旧的更新(就像您在示例中所做的那样)
现在,您仍然可以访问过滤器的productList,但您不必将其包含在依赖项中,依赖项应负责无限重渲染。这里要做的是获取产品列表并根据查询字符串对其进行过滤,然后使用过滤后的列表渲染UI。因此理想情况下,
filteredList
只是基于queryString
和productList
的派生状态。因此,您可以从useEffect中删除filterProducts
,并将其移到外部。这样,当状态发生变化时,它就会运行
function filterProducts (productName = '', productList = []) {
return productName.trim().length > 0 ? productList.filter((prod)=> {
return prod.title === productName;
}); : productList
}
function HomePage () {
const [productList, setProductList] = useState([]);
const [queryString, setQueryString] = useState('');
useEffect(() => {
if (queryString.trim() === "") {
Axios.get("http://localhost:3001/api/product/get-all").then((data) => {
setProductList(data.data);
});
}
}, [queryString]);
// query products is the derived state
const queryProducts = filterProducts(queryString, productList);
// Now instead of using productList to render something use the queryProducts
return (
{queryProducts.map(() => {
.....
})}
)
如果希望仅在queryString
或productList
中的更改时运行filterProducts
,则可以将其包装在UseMoom中
const queryProducts = React.useMemo(() => filterProducts(queryString, productList), [queryString, productList]);
我建议对代码进行一些更改
useffect
拆分,而不是将不同的关注点都混合到一个中(没有规则规定不能有多个useffect
)productList
在依赖项数组中,但是在useffect中调用了setProductList
。如果setProductList
每次设置相同的数据,则不会出现问题。这是否回答了您的问题?谢谢你,这正是我想要的!
const queryProducts = React.useMemo(() => filterProducts(queryString, productList), [queryString, productList]);
const [query, setQuery] = useState('');
const [userInput, setUserInput] = useState('');
useDebounce(userInput, setQuery, 750);
const [products, setProducts] = useState([]);
const [filteredProducts, setFilteredProducts] = useState([]);
useEffect(() => {
if (query.trim() === '') {
Axios
.get("http://localhost:3001/api/product/get-all")
.then((data) => { setProducts(data.data) });
}
}, [query]);
useEffect(
() => setFilteredProducts(filterProducts(userInput, products)),
[userInput, products]
);