首页 > 解决方案 > React hooks如何在初始useEffect之后跳过特定的useEffect

问题描述

我有以下代码,如何防止AsyncStorage.setItem在初始渲染时被调用 2 次?它被调用[]并加载任何内容,AsyncStorage因为logs已更新。完美的解决方案根本不应该调用setItem,因为logs刚刚从AsyncStorage.

const AsyncStorage = require("@react-native-community/async-storage")

const useStore = () => {
  const [logs, setLogs] = useState([])

  useEffect(() => {
    AsyncStorage.getItem("logs").then((newLogs) => setLogs(newLogs));
  }, [])

  useEffect(() => {
    //Don't want to setItem on initial load or when `logs` was just loaded.
    AsyncStorage.setItem("logs", JSON.stringify(logs));
  }, [logs])

  const addLog = (newText) => {
    setLogs(logs => [
      {text: newText, createdAt: new Date().getTime()},
      ...logs,
    ]);
  }

  return {
    logs,
    addLog,
    //...many other functions that update logs
  }
}

标签: reactjsreact-hooks

解决方案


我认为包装你的 set state 方法是一种更简洁的方法来控制日志何时应该发生。像这样的东西:

const AsyncStorage = require("@react-native-community/async-storage")

const useStore = () => {
  const [logs, setLogsState] = useState([])
  const persistLogsRef = useRef(false)

  const setLogs = (updatedLogs) => {
    persistLogsRef.current = true
    setLogsState(updatedLogs)
  }

  useEffect(() => {
    AsyncStorage.getItem("logs").then((newLogs) => setLogsState(newLogs));
  }, [])

  useEffect(() => {
    //Don't want to setItem on initial load or when `logs` was just loaded.
    if (persistLogsRef.current) {
      AsyncStorage.setItem("logs", JSON.stringify(logs));
    }
  }, [logs])

  const addLog = (newText) => {
    setLogs(logs => [
      {text: newText, createdAt: new Date().getTime()},
      ...logs,
    ]);
  }

  return {
    logs,
    addLog,
    //...many other functions that update logs
  }
}

推荐阅读