当结合使用useDispatch和Redux的useSelector时,useEffect进入无限循环

时间:2019-09-13 13:57:25

标签: 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]);

我试图调用API并返回产品,但是该站点始终循环渲染无限。连续渲染无法编辑表单。像

gif

任何人都可以帮助我解决该问题的方法...

p.s:使用此处的代码,它运行正常。但是我想与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]);

p.s:完整代码 code

1 个答案:

答案 0 :(得分:1)

只需从历史记录中获取ID>匹配

  const { history, match } = props;  
  const id = match ? match.params.id : null;

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

  useEffect(() => {
    if (id) {
      dispatch(actGetProductRequest(id));
    }
    setValues(()=>({...getProduct}));
  },[id, getProduct]); 

您的主要问题可能与match对象有关。由于id相同,历史也在不断变化。