useContext 未在同一个渲染器上更新

useContext not updating on the same render

我遇到了一个问题,我需要更新我的 useContext 中的名称,然后立即根据我的代码的另一部分检查它。尽管当我对照另一部分检查它时,上下文中的名称值仍然为空。

所以这是我的上下文文件...

export const UserContext = createContext();

function UserContextProvider(props) {

    const [user, setUser] = useState({
        name: '',
        email: ''
    });

    function updateUser(field, value) {
        return new Promise((resolve, reject) => {
            setUser((prevValue) => {
                return {...prevValue, [field]: value}
            })
            resolve();
        })
        
    }

    return (
        <UserContext.Provider value={{user, updateUser}}>
            {props.children}
        </UserContext.Provider>
    )
}

这就是我想要的 运行...

const { user, updateUser } = useContext(UserContext);    
    async function method(event) {
         event.preventDefault();

        await updateUser("name", "Shaun")
        console.log(user);
    }

我也试过使用 async 和 await,但也没用

我已经在我的 codesandbox 中重现了这个问题:https://codesandbox.io/s/youthful-smoke-fgwlr?file=/src/userContext.js

await in await updateUser("name", "Shaun") 只是等待 Promise at return new Promise((resolve, reject) 没有等待 setUsersetUser 是异步函数(不是 Promise)。所以如果你想检查获取最新的 user 你需要在 App.js

中的另一个 useEffect 中检查它
useEffect(() => {
  console.log(user);
}, [user]);

简单地说:你不能按照你想的那样去做。请注意 user 是一个常量。在 updateUser 中调用 setUser 不会改变 user 仍然绑定到与之前相同的值这一事实。在执行组件的渲染函数期间,任何时候都不会重新分配 user (如果是,您会收到错误,因为它是一个常量)。 user 在您的组件下次刷新并再次调用 useState 之前不会更改(考虑到您刚刚调用了 setUser,这将很快发生)。

就是说,我不确定在调用 setUser 之后检查哪个用例实际上有意义。您已经知道用户的名字应该是 Shaun,所以如果您需要某个值,您已经有了它;检查它是否已分配给 user 根本没有必要或有用。如果您希望您的 updateUser 函数可能对您传递的值进行更改,并且您需要验证该值是否正确,您应该让您的异步函数 return 该值。然后您可以在承诺解决后检查该值。也就是说,无论如何 probably 之类的检查都应该存在于您的 updateUser 函数中;在调用 setUser 之后尝试检查或验证它似乎是一种反模式。