我有一个需要一些复杂数据获取的应用程序。总的来说,这是我的应用程序中逻辑的快照
// dep1 is from redux, dep2 is local state
// useEffect 1
useEffect(() => {
// perform some state variable update to dep2
}, [dep1]);
// useEffect 2
useEffect(() => {
// use some values from deps to fetch data
}, [dep1, dep2]);
我面临的问题是,当 dep1 和/或 dep2 更新时,useEffect 1 的状态更改需要反映在 useEffect 2 中数据获取操作的请求 url 中。useEffect 2 最终运行两次,一次是在 dep1 更新时运行的(没有来自 url 中 useEffect 1 的 dep2 更新)以及一次使用 dep2 更新。在大多数情况下,我们只是渲染,这个问题并不特别明显,但在 useEffect 中使用数据获取的情况下,我们最终会得到两次 api 获取。我可以使用什么策略来规避这种双重 API 调用?
编辑 添加更多代码以使问题更加具体:
// useEffect 1
// when the user is changed (user is a prop that is from redux),
// option should be reset to "DEFAULT"
useEffect(() => {
setOption("DEFAULT");
}, [currentUser]);
// useEffect 2
// option is a value that can be set within the UI and is local state.
// setting option to a new value will trigger api call with new value
useEffect(() => {
const data = await getData(option);
}, [currentUser, option]);
当选项不是“DEFAULT”且当前用户更改时,useEffect 2 将运行两次的问题。我想找到一些逻辑,允许它在当前用户更改时运行一次,并将选项设置回“默认”。使用其他反应模式是否可以实现这一点,因为 useEffect 似乎不可能?
我认为你让事情变得更加复杂了。我建议使用单个效果钩子并计算逻辑并以相同的效果执行数据获取。
/ dep1 is from redux, dep2 is local state
// useEffect 1
useEffect(() => {
// perform some state variable update to dep2
// perform data fetching here and if you want to check some condition for dep2 you could do that here as well.
}, [dep1]);
尝试在当前组件内的 React 组件中设置 dep2 并将其作为 prop 传递,这样每个组件中只有一个 useEffect,并且状态被向上传递。
const component = () => {
useEffect(() => {
// do something
}, [dep1]);
return (
<div> <ComponentTwo depTwo={depTwo}/> </div>
)
}
然后在 ComponentTwo 中...
const componentTwo = ({ depTwo }) => {
// useEffect 2
useEffect(() => {
// use some values from deps to fetch data
}, [dep2]);
return (<div> something </div>
)
}
您需要在父组件中导入 ComponentTwo。
我想找到一些逻辑,允许它在当前用户更改时运行一次,并将选项设置回“默认”。
让我们尽量避免在这两种情况下更新状态。如果我正确理解了这种情况,那么从逻辑上讲,我们正在研究 2 个被视为标志的变量的 4 种排列(布尔值/真值): 变量
对于 (4)(新用户,新选项)的情况,我们通过用户 AI 输入处理组件本身内的选项状态更新,因此无法通过单次重新渲染达到此状态。由于 redux,它正在有效地过渡到 [2],然后由于(且仅在)用户输入之后过渡到 [3]。
让我们确保处理所有情况,这样在每种情况下,我们只调用 API 一次。
代码
const [option, setOption] = useState(null)
案例1、案例2
.
// useEffect 1
// when the user is changed ([currentUser] is a prop that is from redux)
// [we want to render with default options]
useEffect(() => {
const data = await getData("DEFAULT");
}, [currentUser]);
案例3、案例4
// useEffect 2
// option is a value that can be set within the UI and is local state.
// If the user updates the option to a new value [we want to render with user options]
useEffect(() => {
// to avoid two calls on the initial render, add an if statement
if (option){
const data = await getData(option);
}
// else, this is the initial render;
}, [option]);
进一步阅读/解释
由于最后一种情况 (4) 只是处理 (2) 和 (3) 的情况,在它们单独但顺序的状态下,我们已经涵盖了这两个变量的所有排列。
我们可以依靠 useEffect1 来检索默认数据,而不是将选项状态设置为“DEFAULT”,假设我们不使用/要求选项状态执行更多操作而不是获取非默认数据。注意
,使用 null 而不是“DEFAULT”作为选项状态的默认值使我们能够区分初始用户或新用户以及选择默认选项的现有用户,以防用户可以选择“DEFAULT” “作为一个选项。