【问题标题】:Update react-native state using async/await使用 async/await 更新 react-native 状态
【发布时间】:2020-03-08 13:09:13
【问题描述】:

我正在尝试立即更新反应原生的布尔状态变量。但是 await 关键字不起作用。因为状态设置器函数是异步的,我如何使用 async/await 来做到这一点?在vscode中,setLike setter函数前面的await有一条信息:“await has no effect on this type expression”

const likeIt = async () => {
        console.log('like pressed');
        console.log('liked? before set', like);  //**false**
        await setLike(like => !like);
        console.log('liked? after set', like);  //**should be true but getting false**
        const axiosAuth = await axiosWithAuth();
        const userToken = axiosAuth.defaults.headers.Authorization;

        if (like) {
            axiosAuth.post(`https://url`,{})
                .then(res => {
                    console.log('response from post like: ', res.data);
                })
                .catch(err => console.log('error in post like', err.message))
        } else {
            axiosAuth.delete(`https://url`)
                .then(res => console.log('res from unlike', res.data))
                .catch(err => console.log('err from unlike', err))
        }
    }

【问题讨论】:

    标签: reactjs react-native async-await


    【解决方案1】:

    如果我们谈论反应钩子,你应该知道useState() 返回两个值的数组。第二个值是我们用来改变状态值的调度函数。而且这个功能是同步的。 在您的示例中,此调度函数是 setLike() (它是同步函数)。所以await 关键字实际上对他们不起作用。

    React 在底层有一个特殊的系统来处理不断变化的状态。该系统等待一批更改状态,然后更新我们的状态并重新渲染组件。在状态更新和组件重新渲染之前,我们的likeIt()函数将完成。

    您可以使用useEffect() 生命周期方法来处理like 状态的变化。

    例如:

    const likeIt = async () => {
            console.log('like pressed');
            console.log('liked? before set', like);  //**false**
            await setLike(like => !like);
    }
    
    useEffect(() => {
            console.log('liked? after set', like); //**true**
            ...
    }, [like]);
    

    【讨论】:

      【解决方案2】:

      await useState(); 将不起作用。

      这是一个可能的解决方案,它可以在您的 likeIt() 函数中使用临时变量。

      function App() {
        const [like, setLike] = useState(false);
      
         const likeIt = async () => {
           let temp = !like;
      
           const axiosAuth = await axiosWithAuth();
           const userToken = axiosAuth.defaults.headers.Authorization;
      
          if (!temp) {
            axiosAuth.delete(`https://url`)
                    .then(res => console.log('res from unlike', res.data))
                    .catch(err => console.log('err from unlike', err))
          } else {
            axiosAuth.post(`https://url`,{})
                  .then(res => {
                      console.log('response from post like: ', res.data);
                  })
                  .catch(err => console.log('error in post like', err.message))
          }
      
          setLike(temp);
      }
      
        return (
          <div className="App">
            <button onClick={likeIt}>{like === true ? 'Liked' : 'Not Liked'}</button>
          </div>
        );
      }
      

      【讨论】:

      • 非常感谢@chev。为状态变量创建一个临时变量是我需要让函数的逻辑工作。谢谢!
      【解决方案3】:

      您是否因为等待 setLike() 而出现编译错误? 如果不是,这是一个小问题,会让 VScode 上的一些人感到困惑。 请检查https://github.com/microsoft/vscode/issues/80853

      【讨论】:

      • 如果没有,那么你可以忽略它。
      猜你喜欢
      • 1970-01-01
      • 2019-10-27
      • 2019-09-10
      • 2016-11-07
      • 1970-01-01
      • 2017-10-31
      • 2018-10-11
      • 2021-04-01
      • 2016-07-31
      相关资源
      最近更新 更多