关于使用 React 上的钩子排队状态变化的问题
Question about queueing state changes with hooks on React
所以,我通过 class 组件开始学习 React。在那里,据我所知我在做什么,如果我有一个
this.state = {
isLoading: false,
dataToRender: [],
}
this.setState({ isLoading: true }, async () => {
const data = await fetchData();
this.setState({ dataToRender: data , isLoading: false });
})
const message => <p>loading...</p>
if (isLoading) return message();
return (
dataToRender.map
)
每当我为新数据调用 API 时显示“正在加载”消息,我可以知道 setState“队列”将按顺序执行。
外部 setState 将在第一个参数上接收第一个状态更改,并在它之后立即执行一个函数作为第二个参数。
问题是我在想办法用钩子实现这一点时遇到了一些困难。我假设做
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState([]);
setLoading(async () => {
setLoading(true)
const data = await fetchData()
setData(data);
return false;
})
行不通,对吧?我觉得构建这种组件逻辑的整体逻辑在以某种方式使用挂钩时可能会有所不同......如果有人至少可以指出我的概念方向,那就太好了。
谢谢! :)
useState
的调度函数没有回调。
const fn = async () => {
setIsLoading(true)
const data = await fetchData()
setData(data)
setIsLoading(false)
})
上述函数通常在 onClick
或 useEffect
等事件发生时调用。
作为 useState
状态更新函数传递的函数被视为同步函数,因此您有效地将隐式返回的 Promise 对象保存到状态中。
您应该做的是将异步逻辑分解为从事件处理程序调用的函数,如 onClick
,或在组件生命周期中调用的函数,如 useEffect
.
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState([]);
const asyncCall = async () => {
setLoading(true);
try {
const data = await fetchData();
setData(data);
} catch(error) {
// handle any errors, logging, etc...
} finally {
setLoading(false);
}
};
这将 call/enqueue 每个状态按照它们入队的顺序进行更新。您还应该在 try/catch
块中包含任何异步逻辑,以便您可以处理任何被拒绝的承诺,清除 finally
中的加载状态,以便无论 resolved/rejected 承诺如何,当代码完成它时重置加载状态。
取决于 Kent React 通常会批处理这些调用,因此您只会获得一次重新渲染,但它无法在异步回调中执行此操作(例如我们的承诺成功和错误处理程序)。
您可以使用对象作为 useState 的值或使用 useReducer.
const [state,setState]=useState({isLoading:false,success:false,isError:false,data:[]})
然后在每个状态上设置那些 属性。
所以,我通过 class 组件开始学习 React。在那里,据我所知我在做什么,如果我有一个
this.state = {
isLoading: false,
dataToRender: [],
}
this.setState({ isLoading: true }, async () => {
const data = await fetchData();
this.setState({ dataToRender: data , isLoading: false });
})
const message => <p>loading...</p>
if (isLoading) return message();
return (
dataToRender.map
)
每当我为新数据调用 API 时显示“正在加载”消息,我可以知道 setState“队列”将按顺序执行。 外部 setState 将在第一个参数上接收第一个状态更改,并在它之后立即执行一个函数作为第二个参数。
问题是我在想办法用钩子实现这一点时遇到了一些困难。我假设做
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState([]);
setLoading(async () => {
setLoading(true)
const data = await fetchData()
setData(data);
return false;
})
行不通,对吧?我觉得构建这种组件逻辑的整体逻辑在以某种方式使用挂钩时可能会有所不同......如果有人至少可以指出我的概念方向,那就太好了。 谢谢! :)
useState
的调度函数没有回调。
const fn = async () => {
setIsLoading(true)
const data = await fetchData()
setData(data)
setIsLoading(false)
})
上述函数通常在 onClick
或 useEffect
等事件发生时调用。
作为 useState
状态更新函数传递的函数被视为同步函数,因此您有效地将隐式返回的 Promise 对象保存到状态中。
您应该做的是将异步逻辑分解为从事件处理程序调用的函数,如 onClick
,或在组件生命周期中调用的函数,如 useEffect
.
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState([]);
const asyncCall = async () => {
setLoading(true);
try {
const data = await fetchData();
setData(data);
} catch(error) {
// handle any errors, logging, etc...
} finally {
setLoading(false);
}
};
这将 call/enqueue 每个状态按照它们入队的顺序进行更新。您还应该在 try/catch
块中包含任何异步逻辑,以便您可以处理任何被拒绝的承诺,清除 finally
中的加载状态,以便无论 resolved/rejected 承诺如何,当代码完成它时重置加载状态。
取决于 Kent React 通常会批处理这些调用,因此您只会获得一次重新渲染,但它无法在异步回调中执行此操作(例如我们的承诺成功和错误处理程序)。 您可以使用对象作为 useState 的值或使用 useReducer.
const [state,setState]=useState({isLoading:false,success:false,isError:false,data:[]})
然后在每个状态上设置那些 属性。