为什么我的 RXJS 史诗在挂载时无限循环,但在单击按钮时只调用一次?
Why is my RXJS epic in an infinite loop on mount but only called once on button click?
请看下面这段代码
基本上我的行动正在发生的事情被发送到这里:
useEffect(() => {
fetchData()
setLoaded(true)
}, [])
但由于某种原因,这是无限循环并导致我的操作被连续调度
export const fetchData = () => ({ type: 'GET_USER_DATA' })
这触发了我的史诗
const getUserData = (action$, state$) =>
action$.pipe(
ofType('GET_USER_DATA'),
mergeMap(
(action) =>
ajax
.getJSON(
`myurlishere`,
)
.pipe(map((response) => fetchUserFulfilled(response))),
)
)
触发这个:
const fetchUserFulfilled = (payload) => ({ type: 'GET_DATA_SUCCESS', data: payload })
此代码一切正常,但它在无限循环中不断调用它
但是,如果我将代码从 useEffect
移动到按钮调用,如下所示:
<button onClick={fetchData}>fetch</button>
它只调用一次,这就是我想要的
但是我需要调用onmount的数据。那我该如何解决呢?
请注意,我已尝试向 useEffect 的第二个参数添加各种内容,但没有效果
useEffect(() => {
fetchData()
setLoaded(true)
}, [user.id])
仅根据提供的代码,我没有发现任何问题。我的直觉提出了一些选择,即使你提到了其中一些,我也会 三重检查 :
- 缺少依赖项数组作为 useEffect 的第二个参数,或者您正在为其使用一个变量,但该变量具有
undefined
值,这会产生同样的问题。
- 如果您正在使用 useEffect 依赖项,那么其中一个可能会在不知不觉中不断变化。例如对象经常在渲染之间改变身份,
{} !== {}
- 未显示的代码也在分派相同的操作,实际上 useEffect 仅 运行 一次。
- 一些父级正在使用
key={something}
渲染其中一个祖先或此组件,并且提供的值在每次渲染时都会发生变化。如果发生这种情况,每次都会从头开始重新创建组件。
如果你 100% 肯定你提供 useEffect(work, [])
,一个空数组作为第二个参数,但实际上效果在无限循环中被确认为 运行,同步,然后第四种可能。
如果您在发布此问题时在问题中手动键入这些代码示例,请不要相信您实现它们的方式与您认为您的应用正在执行的方式相同。三重检查。最好让其他人检查谁没有编写代码。通常问题是我们认为我们已经告诉我们的代码做什么,而不是我们实际告诉它做什么。如果您还没有这样做,最好的办法是使用调试器单步调试代码,这样您就可以看到发生了什么。
希望对您有所帮助!
这是现在有效的代码:
export const getUserDataEpic = () => {
return ajax
.getJSON(myurl)
.pipe(
map((response) => fetchUserFulfilled(response)),
)
}
我知道我现在没有在听触发的动作,但为什么会导致无限循环?
请看下面这段代码
基本上我的行动正在发生的事情被发送到这里:
useEffect(() => {
fetchData()
setLoaded(true)
}, [])
但由于某种原因,这是无限循环并导致我的操作被连续调度
export const fetchData = () => ({ type: 'GET_USER_DATA' })
这触发了我的史诗
const getUserData = (action$, state$) =>
action$.pipe(
ofType('GET_USER_DATA'),
mergeMap(
(action) =>
ajax
.getJSON(
`myurlishere`,
)
.pipe(map((response) => fetchUserFulfilled(response))),
)
)
触发这个:
const fetchUserFulfilled = (payload) => ({ type: 'GET_DATA_SUCCESS', data: payload })
此代码一切正常,但它在无限循环中不断调用它
但是,如果我将代码从 useEffect
移动到按钮调用,如下所示:
<button onClick={fetchData}>fetch</button>
它只调用一次,这就是我想要的
但是我需要调用onmount的数据。那我该如何解决呢?
请注意,我已尝试向 useEffect 的第二个参数添加各种内容,但没有效果
useEffect(() => {
fetchData()
setLoaded(true)
}, [user.id])
仅根据提供的代码,我没有发现任何问题。我的直觉提出了一些选择,即使你提到了其中一些,我也会 三重检查 :
- 缺少依赖项数组作为 useEffect 的第二个参数,或者您正在为其使用一个变量,但该变量具有
undefined
值,这会产生同样的问题。 - 如果您正在使用 useEffect 依赖项,那么其中一个可能会在不知不觉中不断变化。例如对象经常在渲染之间改变身份,
{} !== {}
- 未显示的代码也在分派相同的操作,实际上 useEffect 仅 运行 一次。
- 一些父级正在使用
key={something}
渲染其中一个祖先或此组件,并且提供的值在每次渲染时都会发生变化。如果发生这种情况,每次都会从头开始重新创建组件。
如果你 100% 肯定你提供 useEffect(work, [])
,一个空数组作为第二个参数,但实际上效果在无限循环中被确认为 运行,同步,然后第四种可能。
如果您在发布此问题时在问题中手动键入这些代码示例,请不要相信您实现它们的方式与您认为您的应用正在执行的方式相同。三重检查。最好让其他人检查谁没有编写代码。通常问题是我们认为我们已经告诉我们的代码做什么,而不是我们实际告诉它做什么。如果您还没有这样做,最好的办法是使用调试器单步调试代码,这样您就可以看到发生了什么。
希望对您有所帮助!
这是现在有效的代码:
export const getUserDataEpic = () => {
return ajax
.getJSON(myurl)
.pipe(
map((response) => fetchUserFulfilled(response)),
)
}
我知道我现在没有在听触发的动作,但为什么会导致无限循环?