5Mi / wumi_blog

for recording improvimg my experience
21 stars 0 forks source link

react小记 #87

Open 5Mi opened 2 years ago

5Mi commented 2 years ago

useState is async , use for re-render first You can pass a function to the useState hook to have your value lazily initialized. the pass function only run once

const [state, setState] = useState(() => {
  const initialState = someExpensiveComputation(props);
  return initialState;
});
const [info, setInfo] = useState([]);

const fetchInfo = async () => {
  const res = await someApi();
  setInfo(res);
};

useEffect(() => {
  (async () => {
    await fetchInfo();
    // 由于setInfo 为异步
    // 此时info不是最新值
    // 此时setInfo([]) 会覆盖上一次setInfo

    // 如果需要获取最新值, 或setInfo 可以通过下面的方式
    setInfo((previous) => {
      // 获取previous state

      // 再返回操作后需要set的值
      return [...previous, {}];
    });
  })();
}, []);
// https://dev.to/bytebodger/synchronous-state-with-react-hooks-1k4f
export const useSyncState = <T,>(
  initialState: T
): [() => T, (newState: T) => void] => {
  const [state, updateState] = useState(initialState);
  let current = state;
  const get = (): T => current;
  const set = (newState: T) => {
    current = newState;
    updateState(newState);
    return current;
  };
  return [get, set];
};

export const usePromiseAwait = () => {
  const promiseResolver = useRef<any>(null);
  const [promiseAwait] = useState(
    () =>
      new Promise((resolve) => {
        promiseResolver.current = resolve;
      })
  );

  return [promiseAwait, promiseResolver.current];
};

参考 effect hook 在不同组件之间的执行顺序遵从如下规律:

组件渲染后,执行 effect 的顺序:组件树的后序深度优先遍历 组件重新渲染时,清除 effect 的顺序:组件树的后序深度优先遍历 组件 unmount 时,清除 effect 的顺序:组件树的前序深度优先遍历

useEffect 模拟 shouldComponentUpdate

useEffect(() => {
  // 无依赖数组, 每次渲染之后执行

  return () => {
    // 下次渲染之前
  };
});

useEffect 模拟 componentDidMount

useEffect(() => {
  // 依赖数组无变化, 首次渲染之后执行
}, []);

useEffect 模拟 componentWillUnmount

useEffect(() => {
  // 依赖数组无变化, 首次渲染之后执行

  return () => {
    // 依赖数组无变化 即为Unmount时 清除上面的副作用
  };
}, []);