React Hooks 状态总是落后一步

React Hooks state always a step behind

我在重置页面 = 1 时遇到问题。在 handleSearchClick 我有 setPage(1) 但它的一次点击晚了,所以在第二次点击后页面将重置为 1

This is my current code

const [page, setPage] = React.useState(1);
//Other states as well 

    /**
     * Handles event on search click
     */
    const handleSearchClick = async () => {
        setItems([]);
        const database = handleBaseId();
        setPage(1);
        const items = await fetchSearchPayload(page, value, option, database);
        setIsLoading(false);
        setItems(items);
    };

我也尝试在按钮中重置页面,但收到 react limits the number of renders to prevents an infinite loop 错误消息

This is what I tried doing

<SearchBar
     onClickButton={handleSearchClick}
     onValueChange={handleChange}
     value={value}
     pageNum={page}
     onEnter={handleSearchOnEnter}>

   {setPage(1)}

</SearchBar>

我也尝试使用 useEffect 并添加了一个 count 状态,每次单击 searchBar 时该状态都会增加,但我遇到了计数本身落后一步的问题。

const [count, setCount] = React.useState(0);

React.useEffect(() => {
        setPage(1);
    }, [count]);

    /**
     * Handles event on search click
     */
    const handleSearchClick = async () => {
        setCount(count+1);
        setItems([]);
        const database = handleBaseId();
        setPage(1);
        const items = await fetchSearchPayload(page, value, option, database);
        setIsLoading(false);
        setItems(items);
    };

如有任何关于如何立即重置 page 的建议,我们将不胜感激!

您似乎在尝试设置页面(异步),然后立即在 fetchSearchPayload 调用中使用 page 状态。考虑到您总是在硬编码中将页面设置为 1,您也可以在 fetchSearchPayload 调用中对 1 进行硬编码。

您可以采用的另一种方法是仅在页面更新时通过执行以下操作进行异步调用:

React.useEffect(() => {
    const database = handleBaseId();
    const items = await fetchSearchPayload(page, value, option, database);
    setIsLoading(false);
    setItems(items);
}, [ page ]);

/**
 * Handles event on search click
 */
const handleSearchClick = async () => {
    setItems([]);
    setPage(1);
};

问题是状态更新与钩子状态更新器是异步的,就像 setState 在 React 组件中一样。解决方案是手动传递页面来运行而不是依赖状态

/**
 * Handles event on search click
 */
const handleSearchClick = async () => {
    setItems([]);
    const database = handleBaseId();
    setPage(1);
    const items = await fetchSearchPayload(1, value, option, database);
    setIsLoading(false);
    setItems(items);
};