首页 > 解决方案 > 使用箭头函数方法从 useState 调用 set 函数过早重新加载

问题描述

所以当http请求在自定义钩子中失败时,我试图在上下文中设置一个数组

这是我的钩子:

const useHttp = (requestObj: any, setData: Function) => 
{
    const [isLoading, setIsLoading] = useState(false); 
    const ctx = useContext(GlobalContext);
        
    const sendRequest = useCallback(() =>
    {
        setIsLoading(true);
        
        fetch(requestObj.url, {
            method: requestObj.method ? requestObj.method: 'GET',
            headers: requestObj.headers ? requestObj.headers : {},
            body: requestObj.body ? JSON.stringify(requestObj.body) : null
        })
        .then(res => res.json())
        .then(data => {
            setIsLoading(false);
            setData(data);                
        })
        .catch(err => 
        {
            setIsLoading(false); 
            ctx.setErrors([
            (prevErrors: string[]) =>
            {
                //prevErrors.push(err.message)
                let newArray = prevErrors.map((error) => {return error});
                newArray.push(err.message);
                return newArray;
            }]
        );
            console.log('There was an error');
        });
    }, []);

    return {
        isLoading: isLoading,
        sendRequest: sendRequest
    }
} 

我使用先前的状态值设置数组。我使用 .map 因为数组的扩展运算符不起作用。我正在研究它,但它对此并不重要。

当它遇到 setErrors 时,它似乎会导致使用它的组件的显示(如下)。我认为它不会更新,直到函数被触发。那么问题是,当它重新评估错误时,是一个数组,其中第一个元素中包含来自钩子的函数。所以我不知道在这里做什么

const App: FC = () => {

    const [errors, setErrors] = useState([]);

    let modal = null

    if(errors.length > 0)
    {
        modal = ( 
            <Modal 
                heading="Warning" 
                content={<div>{errors}</div>}
                buttonList={
                    [
                        {label: "OK", clickHandler: ()=> {}, closesModal: true},
                        {label: "Cancel", clickHandler: ()=> {alert("cancelled")}, closesModal: false}
                    ]
                } 
                isOpen={true}/>
        )
    }

    return (
        <GlobalContext.Provider value={{errors: errors, setErrors: setErrors}}>
            <ProviderV3 theme={defaultTheme}>
                <Toolbar></Toolbar>
                <Grid
                    margin='25px'
                    columns='50% 50%'
                    gap='10px'
                    maxWidth='100vw'>
                    <OwnerSearch />
                    <NewOwnerSearch />
                </Grid>
            </ProviderV3>
            {modal}
        </GlobalContext.Provider>
    );
};

标签: reactjs

解决方案


您不小心在函数周围放置了数组括号:

ctx.setErrors((prevErrors: string[]) => {
  //prevErrors.push(err.message)
  let newArray = prevErrors.map((error) => {return error});
  newArray.push(err.message);
  return newArray;
})

推荐阅读