在函数调用之前设置React挂钩状态

时间:2019-05-20 05:40:48

标签: reactjs promise react-hooks

在调用page = 1中的handleSearchClick函数之前,无法设置resetStates。当前,在调用resetStates时(在单击search button之后),第一次单击时不会将页面重置为1,而第二次搜索时会将页面重置为1。

我尝试使用async await,但是在handleSearchClick之前并没有将页面重置为1。如何在函数调用前将页面重置为1?任何反馈表示赞赏。

这是我目前正在做的事情:

const resetStates = async () => {
            const promise1 = setHasMore(true);
            const promise2 = await setPage(1);
            Promise.all([promise1, promise2])
                .then(() => {
                 /* At this point I want page to equal 1 */
                    handleSearchClick(); 
                })
                .catch(error => {
                    throw new Error(error);
                });
        };

    /**
     * Handles event on search click
     */
    const handleSearchClick = async () => {
        setItems([]);
        setIsLoading(true);
        const base = handleBaseId();
        const items = await fetchSearchPayload(page, value, option, base);
        setIsLoading(false);
        setInitialLoad(true);
        setItems(items);
        console.log('On Click', { option }, { page });
    };

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

1 个答案:

答案 0 :(得分:2)

state updater is asynchronous,但它不会向您返回承诺,因此您不能使用await等待承诺完成。相反,您可以将页面值作为参数传递

    const resetStates = async () => {
            setHasMore(true);
            setPage(1);
            handleSearchClick(1); 
    };

    /**
     * Handles event on search click
     */
    const handleSearchClick = async (page) => {
        setItems([]);
        setIsLoading(true);
        const base = handleBaseId();
        const items = await fetchSearchPayload(page, value, option, base);
        setIsLoading(false);
        setInitialLoad(true);
        setItems(items);
        console.log('On Click', { option }, { page });
    };

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

否则您可以利用useEffect等待状态更新

const prevPage = usePrevious(page);
const prevHasMore = usePrevious(hasMore);
const initialRender = useRef(true);
useEffect(() => {
   if(initialRender.current !== true) {
        // you can check for hasMore also here
        if((prevPage !== page && page == 1) && (prevHasMore !== hasMore && hasMore === true)) {
            handleSearchClick();
        }
   }
}, [hasMore, page])

const resetStates = async () => {
        setHasMore(true);
        setPage(1);

};

/**
 * Handles event on search click
 */
const handleSearchClick = async (page) => {
    setItems([]);
    setIsLoading(true);
    const base = handleBaseId();
    const items = await fetchSearchPayload(page, value, option, base);
    setIsLoading(false);
    setInitialLoad(true);
    setItems(items);
    console.log('On Click', { option }, { page });
};

您可以从下面的帖子中参考usePrevious的实现

How to compare oldValues and newValues on React Hooks useEffect?