Reactjs 如何在初始useEffect之后跳过特定useEffect
我有以下代码,如何防止在初始渲染时调用Reactjs 如何在初始useEffect之后跳过特定useEffect,reactjs,react-hooks,Reactjs,React Hooks,我有以下代码,如何防止在初始渲染时调用AsyncStorage.setItem?它通过[]和从AsyncStorage加载的任何内容调用,因为日志已更新。完美的解决方案根本不应该调用setItem,因为日志刚刚从异步存储中检索 const AsyncStorage = require("@react-native-community/async-storage") const useStore = () => { const [logs, setLogs] = u
AsyncStorage.setItem
?它通过[]
和从AsyncStorage
加载的任何内容调用,因为日志
已更新。完美的解决方案根本不应该调用setItem
,因为日志
刚刚从异步存储
中检索
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
}
}
您可以使用ref作为是否允许设置日志的标志
const AsyncStorage = require("@react-native-community/async-storage")
const useStore = () => {
const [logs, setLogs] = useState([]);
const allowSettingLogs = React.useRef(false);
useEffect(() => {
AsyncStorage.getItem("logs").then((newLogs) => setLogs(newLogs));
}, [])
useEffect(() => {
//Don't want to setItem on initial load or when `logs` was just loaded.
if (allowSettingLogs.current) AsyncStorage.setItem("logs", JSON.stringify(logs));
}, [logs])
const addLog = (newText) => {
allowSettingLogs.current = true;
setLogs(logs => [
{text: newText, createdAt: new Date().getTime()},
...logs,
]);
}
return {
logs,
addLog,
//...many other functions that update logs
}
}
您可能希望包装
useffect
,并使其忽略第一个更改
const useffectigningfirstchange=(fn,deps)=>{
const firstCallRef=useRef(true);
useffect(()=>{
if(firstCallRef.current){
firstCallRef.current=false;
返回;
};
fn()
},副署长);
}
常量useStore=()=>{
const[logs,setLogs]=useState([])
useffect(()=>{
AsyncStorage.getItem(“日志”)。然后((newLogs)=>setLogs(newLogs));
}, [])
useEffectIgnoringFirstChange(()=>{
//不希望在初始加载时或刚加载'logs'时设置项。
AsyncStorage.setItem(“logs”,JSON.stringify(logs));
},[日志])
常量addLog=(新文本)=>{
设置日志(日志=>[
{text:newText,createdAt:new Date().getTime()},
…日志,
]);
}
返回{
日志,
addLog,
//…许多其他更新日志的功能
}
}
这就是我最终得到的,我仍然想知道这是否是最好的解决方案,因此欢迎使用更优雅的解决方案:
const AsyncStorage = require("@react-native-community/async-storage")
const useStore = () => {
const justLoaded = useRef(true);
const [logs, setLogs] = useState([])
useEffect(() => {
AsyncStorage.getItem("logs").then((newLogs) => {
justLoaded.current = true;
setLogs(newLogs));
}
}, [])
useEffect(() => {
//Don't want to setItem on initial load or when `logs` was just loaded.
if (justLoaded.current === false) AsyncStorage.setItem("logs", JSON.stringify(logs));
if (justLoaded.current) justLoaded.current = false;
}, [logs])
const addLog = (newText) => {
setLogs(logs => [
{text: newText, createdAt: new Date().getTime()},
...logs,
]);
}
return {
logs,
addLog,
//...many other functions that update logs
}
}
我认为包装setstate方法是一种更干净的方法,可以控制何时应该发生日志持久化。大概是这样的:
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
}
}
因此,本质上,您希望将其用作
componentdiddupdate
hook?您可以编写一个忽略第一个更改的hook。?这仍然会调用AsyncStorage.setItem(“logs”,JSON.stringify(logs))代码>在第一次useEffect设置日志后。您可以使用ref检查更新。我已经更新了上面的代码。我不愿意将allowSettingLogs.current=true
添加到我所有更新logs
的函数中,尽管有addLog、deleteLog、updateLog。。。。有没有办法只在AsyncStorage.getItem
行中添加标记?对于刚从AsyncStorage检索到的日志,它仍将调用一次。可以修改为使用计数。我认为这是一个关于如何传播数据的更大问题的迹象。你有没有考虑过使用redux?