mlz*_*lz7 8 javascript firebase reactjs redux react-redux
我正在尝试通过 redux-thunk 操作查询我的 Firebase 后端,但是,当我在使用 的初始渲染中这样做时useEffect(),我最终遇到此错误:
Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
Run Code Online (Sandbox Code Playgroud)
我的操作只是返回一个 Firebase 查询快照,然后我在我的减速器中收到了它。我使用钩子来调度我的动作:
export const useAnswersState = () => {
return {
answers: useSelector(state => selectAnswers(state)),
isAnswersLoading: useSelector(state => selectAnswersLoading(state))
}
}
export const useAnswersDispatch = () => {
const dispatch = useDispatch()
return {
// getAnswersData is a redux-thunk action that returns a firebase snapshot
setAnswers: questionID => dispatch(getAnswersData(questionID))
}
}
Run Code Online (Sandbox Code Playgroud)
和以下选择器从我的快照和 redux 状态中获取我需要的数据:
export const selectAnswers = state => {
const { snapshot } = state.root.answers
if (snapshot === null) return []
let answers = []
snapshot.docs.map(doc => {
answers.push(doc.data())
})
return answers
}
export const selectAnswersLoading = state => {
return state.root.answers.queryLoading || state.root.answers.snapshot === null
}
Run Code Online (Sandbox Code Playgroud)
在我的实际组件中,我尝试首先通过调度我的操作来查询我的后端,然后在数据加载后尝试读取结果数据,如下所示:
const params = useParams() // params.id is just an ID string
const { setAnswers, isAnswersLoading } = useAnswersDispatch()
const { answers } = useAnswersState()
useEffect(() => {
setAnswers(params.id)
}, [])
if (!isAnswersLoading)) console.log(answers)
Run Code Online (Sandbox Code Playgroud)
所以为了澄清,我正在使用 myuseAnswersDispatch来调度一个 redux-thunk 操作,该操作返回一个 firebase 数据快照。然后我使用我的useAnswersState钩子在加载数据后访问它。我试图在useEffect我的实际视图组件中调度我的查询,然后使用我的状态钩子显示数据。
但是,当我尝试打印 的值时answers,我从上面收到错误。我将不胜感激任何帮助,如果这有帮助,我很乐意提供更多信息,但是,我已经测试了我的减速器和操作本身,它们都按预期工作,所以我相信问题出在文件中如上所述。
lau*_*nat -1
尝试重构您的动作创建器,以便dispatch在效果中调用它。您需要根据效果触发来进行调度。
const setAnswers = (params.id) => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(useAnswersDispatch(params.id));
}, [])
}
Run Code Online (Sandbox Code Playgroud)
假设getAnswersData是一个选择器,效果将触发分派到您的应用程序状态,当您收到响应时,您的选择器getAnswersData将选择您想要的字段。
我不确定params.id它来自哪里,但您的组件依赖它来确定应用程序状态的答案。
触发调度后,仅更新应用程序状态,而不更新组件状态。使用 设置变量useDispatch,您可以在组件的生命周期中获得对 redux 存储的调度函数的变量引用。
要回答您的问题,如果您希望它处理多个调度,请将params.id和添加dispatch到效果中的依赖项数组中。
// Handle null or undefined param.id
const answers = (param.id) => getAnswersData(param.id);
const dispatch = useDispatch();
useEffect(() => {
if(params.id)
dispatch(useAnswersDispatch(params.id));
}, [params.id, dispatch]);
console.log(answers);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1516 次 |
| 最近记录: |