useEffect 在结合 useDispatch、Redux 的 useSelector 时进入无限循环

vod*_*anh 5 reactjs react-redux react-hooks

我尝试使用 react-hook 和 redux 进行状态管理编码,使用 axios 进行数据库请求编码,使用 Thunk 作为中间件处理异步性。我在一个组件中遇到问题,该组件执行 get 请求以检索过去的客户列表是 componentwillreceiveprop

# Action
export const actGetProductRequest = id => dispatch =>
  callApi(`products/${id}`, "GET").then(res =>
    dispatch({
      type: types.EDIT_PRODUCT,
      payload: { product: res.data }
    })
  );

------
import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import useForm from "./useForm";
import { actGetProductRequest } from "../../actions";
...
const { history, match } = props;
  const getProduct = useSelector(state => state.itemEditing);
  const dispatch = useDispatch();
  const { values, setValues, handleChange, handleSubmit } = useForm(
    getProduct,
    history
  );  
  useEffect(() => {
    if (match) {
      let id = match.params.id;
      dispatch(actGetProductRequest(id));
    }
    setValues(()=>({...getProduct}));
  },[match,dispatch, setValues, getProduct]);
Run Code Online (Sandbox Code Playgroud)

我尝试调用 API 并返回产品,但该站点总是无限循环渲染。无法编辑连续呈现的表单。像

gif

任何人都可以请帮我解决这个问题...

ps:这里有代码,运行正常。但是我想和redux一起使用,我把调用axios的代码传给dispatch和redux,返回新的改变状态

 useEffect(() => {
    if (match) {
      let id = match.params.id;
      callApi(`products/${id}`, "GET", null).then(res => {
        const data = res.data;
        setValues(()=>({...data}));
      });      
    }
    const clearnUp = () => setValues(false);
    return clearnUp;
  },[match, setValues]);
Run Code Online (Sandbox Code Playgroud)

ps:完整 代码

Pra*_*uri 2

只需从历史记录>匹配中获取id即可

  const { history, match } = props;  
  const id = match ? match.params.id : null;
Run Code Online (Sandbox Code Playgroud)

您不需要添加dispatch依赖项。使用 代替匹配id。并且您可以跳过方法引用。由于setValues基本上是一个setState调用,因此也可以跳过它(阅读 React 文档)。但如果您确实想在依赖项中使用任何函数引用,请确保将它们用useCallback.

  useEffect(() => {
    if (id) {
      dispatch(actGetProductRequest(id));
    }
    setValues(()=>({...getProduct}));
  },[id, getProduct]); 
Run Code Online (Sandbox Code Playgroud)

您的主要问题可能与该对象有关match。因为,即使历史id是一样的,历史也在不断变化。

  • 如果您需要更好的帮助,请显示完整的示例。仅凭一小段代码很难猜测无限循环是从哪里来的 (2认同)