【问题标题】:How to make setState synchronous in functional component如何在功能组件中使 setState 同步
【发布时间】:2022-11-29 21:55:30
【问题描述】:

我已经使用了 flushSync,但我仍然遇到 setState 在渲染页面后运行的问题

const dispatch = useDispatch();

  const [isAuthenticated, setIsAuthenticated] = useState(false)
  const { user, loading } = useSelector(selectUserSlice);

  useLayoutEffect(() => {
    if (user?._id) {
      // @ts-ignore
      dispatch(getUserDetailsThunk()).then(x => {
        if (x?.payload?._id && user._id && x.payload._id === user._id) flushSync(setIsAuthenticated(true))
      })
    }
  }, [])

  return (
    <>
      {loading ? (
        <div className="flex h-screen justify-center items-center"><ClipLoader color="#36d7b7" /></div>
      ) : !isAuthenticated ? <Custom404 /> : <header className="py-6 bg-white"></header>}
    </>)

问题是fulfill dispatch(getUserDetailsThunk())后会渲染这个页面,此时isAuthenticated为false,页面会渲染404Page,然后触发flushSync(setIsAuthenticated(true)),设置isAuthenticated为true ,然后页面再次重新呈现。

这就是为什么我想在 dispatch(getUserDetailsThunk()) fulfill 之后将 isAuthenticated 设置为 true,因此页面显示主页而不首先呈现 404page。

有没有人知道该怎么做?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    问题解决: 1/ 创建一个名为 useTrait 的自定义钩子:

    import { useState } from 'react';
    
    export default function useTrait(initialValue) {
       const [trait, updateTrait] = useState(initialValue);
    
       let current = trait;
    
       const get = () => current;
    
       const set = newValue => {
          current = newValue;
          updateTrait(newValue);
          return current;
       }
    
       return {
          get,
          set,
       }
    }

    然后使用那个自定义钩子而不是原来的 useState 钩子

      // const [isAuthenticated, setIsAuthenticated] = useState(false)
      const isAuthenticated = useTrait(false)
      const { user, loading } = useSelector(selectUserSlice);
    
      useLayoutEffect(() => {
        if (user?._id) {
          // @ts-ignore
          dispatch(getUserDetailsThunk()).then(x => {
            if (x?.payload?._id && user._id && x.payload._id === user._id){
              isAuthenticated.set(true)
            }
          })
        }
      }, [])

    我认为很多开发人员也遇到了这个问题。 希望这可以帮助

    【讨论】:

      猜你喜欢
      • 2021-04-20
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      • 2021-11-23
      • 2018-01-15
      • 2021-03-07
      • 2020-08-04
      相关资源
      最近更新 更多