Reactjs React Redux-如何进行双重分派

Reactjs React Redux-如何进行双重分派,reactjs,react-redux,Reactjs,React Redux,我正在从我的API中获取一些数据,它正常工作。但是当在同一页上进行双重分派时,API就不再工作了。最好用代码来解释它: 服务器: router.get("/", (req, res) => { let sql = "SELECT * FROM design_categories"; let query = connection.query(sql, (err, results) => { if (err) throw err;

我正在从我的API中获取一些数据,它正常工作。但是当在同一页上进行双重分派时,API就不再工作了。最好用代码来解释它:

服务器:

router.get("/", (req, res) => {
  let sql = "SELECT * FROM design_categories";
  let query = connection.query(sql, (err, results) => {
    if (err) throw err;
    res.header("Access-Control-Allow-Origin", "*");
    res.send(results);
  });
});
 
router.get("/", (req, res) => {
  let sql = "SELECT * FROM food_categories";
  let query = connection.query(sql, (err, results) => {
    if (err) throw err;
    res.header("Access-Control-Allow-Origin", "*");
    res.send(results);
  });
});
他们工作

action.js

export const fetchDesignCat = () => {
  setLoading()
  return async dispatch => {
    const response = await axios
      .get("http://localhost:5000/api/designcategories")
      .then(results => results.data)

    try {
      await dispatch({ type: FETCH_DESIGN_CAT, payload: response })
    } catch (error) {
      console.log("await error", error)
    }
  }
}
     
export const fetchFoodCat = () => {
  setLoading()
  return async dispatch => {
    const response = await axios
      .get("http://localhost:5000/api/foodcategories")
      .then(results => results.data)

    try {
      await dispatch({ type: FETCH_FOOD_CAT, payload: response })
    } catch (error) {
      console.log("await error", error)
    }
  }
}
他们两个都工作得很好

reducer.js

const initalState = {
  db: [],
  loading: true,
  designcat: [],
  foodcat: [],
}
export default (state = initalState, action) => {
 switch (action.type) {
// different cases

  case FETCH_DESIGN_CAT:
      return {
        designcat: action.payload,
        loading: false,
      }
    case FETCH_FOOD_CAT:
      return {
        food: action.payload,
        loading: false,
      }

}
减速器可以完美地更新状态

页面设置.js

const Settings = ({ designcat, foodcat, loading }) => {
  const dispatch = useDispatch()

// ... code 


useEffect(() => {
    dispatch(fetchDesignCat()) // imported action
    dispatch(fetchFoodCat()) // imported action
    // eslint-disable-next-line
  }, [])

// ... code that renders 

const mapStateToProps = state => ({
  designcat: state.appDb.designcat,
  foodcat: state.appDb.foodcat,
  loading: state.appDb.loading,
})

export default connect(mapStateToProps, { fetchDesignCat, fetchFoodCat })(
  Settings
)
现在问题来了。如果我只使用一个调度,我就可以得到一个或另一个。但是,如果我使用这两种方法,它们看起来就像,如果第二种方法覆盖了第一种方法。这听起来很奇怪

从我的ReduxDevTools

我肯定在什么地方弄错了。有什么想法吗


谢谢

reducer不会将现有状态与新状态合并,这就是为什么每个操作都会替换以前的状态。您需要复制状态的其他属性,并且只替换您的特定操作应该替换的属性。在这里,我使用的是前一个状态的浅拷贝:

export default (state = initalState, action) => {
  switch (action.type) {
    case FETCH_DESIGN_CAT:
      return {
        ...state, // <----
        designcat: action.payload,
        loading: false,
      }
    case FETCH_FOOD_CAT:
      return {
        ...state, // <----
        food: action.payload,
        loading: false,
      }
  }
}
代码中还有一个竞争条件,这对您来说可能是问题,也可能不是问题。由于同时启动FETCH_DESIGN_CAT和FETCH_FOOD_CAT,并且它们都在完成后设置loading:false,因此当第一个操作完成时,加载将为false,但另一个操作仍将加载其数据。如果这种情况是已知的,并且是在代码中处理的,例如,如果加载为false,您不相信这两个项都会出现在状态中,那么也可以


解决方案是将这两个类别的获取合并到一个thunk中,或者使用它们自己的加载状态属性为它们创建单独的子缩减器。当然,您也可以手动设置和取消设置加载。

您的reducer不会将现有状态与新状态合并,这就是为什么每个操作都会替换以前的状态。您需要复制状态的其他属性,并且只替换您的特定操作应该替换的属性。在这里,我使用的是前一个状态的浅拷贝:

export default (state = initalState, action) => {
  switch (action.type) {
    case FETCH_DESIGN_CAT:
      return {
        ...state, // <----
        designcat: action.payload,
        loading: false,
      }
    case FETCH_FOOD_CAT:
      return {
        ...state, // <----
        food: action.payload,
        loading: false,
      }
  }
}
代码中还有一个竞争条件,这对您来说可能是问题,也可能不是问题。由于同时启动FETCH_DESIGN_CAT和FETCH_FOOD_CAT,并且它们都在完成后设置loading:false,因此当第一个操作完成时,加载将为false,但另一个操作仍将加载其数据。如果这种情况是已知的,并且是在代码中处理的,例如,如果加载为false,您不相信这两个项都会出现在状态中,那么也可以

解决方案是将这两个类别的获取合并到一个thunk中,或者使用它们自己的加载状态属性为它们创建单独的子缩减器。当然,您也可以手动设置和取消设置加载。

正如您所知,指的是特定的软件工程概念:正如您所知,指的是特定的软件工程概念: