【问题标题】:Redux saga enters in infinite loop state of calling api endpointRedux saga 进入调用 api 端点的无限循环状态
【发布时间】:2020-12-15 20:17:07
【问题描述】:

我使用 Redux 进行状态管理,并将 saga 作为中间件。由于某种原因,我的应用程序处于调用 API 端点的无限循环状态。

这是我的行动:

export const GET_USERS = "GET_USERS";
export const getUsers = () => ({
  type: GET_USERS,
});

export const GET_USERS_SUCCESS = `${GET_USERS}_SUCCESS`;
export const getUsersSuccess = (data) => ({
  type: GET_USERS_SUCCESS,
  payload: data,
});

export const GET_USERS_FAIL = `${GET_USERS}_FAIL`;
export const getUsersFail = (error) => ({
  type: GET_USERS_FAIL,
  payload: error,
});

这是传奇:

export function* getUsers$() {
  try {
    const users = yield getUsersAPI();
    yield put(actions.getUsersSuccess(users.data));
  } catch (error) {
    yield put(actions.getUsersFail(error));
  }
}

export default function* () {
  yield all([takeLatest(actions.getUsers, getUsers$)]);
}

这是一个减速器:

export default (state = initialState(), action) => {

  const { type, payload } = action;

  switch (type) {
    case actions.GET_USERS:
      return {
        ...state,
        users: {
          ...state.users,
          inProgress: true,
        },
      };
    case actions.GET_USERS_SUCCESS:
      return {
        ...state,
        users: {
          inProgress: false,
          data: payload,
        },
      };
    case actions.GET_USERS_FAIL:
      return {
        ...state,
        users: {
          ...state.users,
          inProgress: false,
          error: payload,
        },
      };
    default:
      return state;
  }
};

这是一个与redux连接的组件:

const Home = (props) => {

    useEffect(() => {
        props.getUsers();
        console.log('props', props.data);
    }, []);
   return(
    <h1>Title</h1>
   );
}

const mapStateToProps = ({
    users: {
        users: {
            data
        }
    }
}) => ({data})


export default connect(mapStateToProps, {getUsers})(Home);

为什么会这样?

【问题讨论】:

    标签: reactjs react-redux redux-saga


    【解决方案1】:

    这是因为您在示例中误用了sagas。与任何其他effect creator 一样,第一个参数必须传递pattern,可以在文档中更详细地阅读。第一个参数也可以传递function,但方式略有不同。查看documentation(阻止take(pattern))。

    在您的情况下,您正在传递一个将返回一个对象的函数

    {
      type: 'SOME_TYPE',
      payload: 'some_payload',
    }
    

    因此,您的worker 将对您dispatchALL 事件作出反应。 结果,您从服务器接收数据,dispatch 一个新的action 以保存来自存储的数据。除了reducer,您的getUsers 传奇也将被调用。以此类推,无止境。

    解决方案

    要解决这个问题,只需使用您在操作中定义的字符串常量actions.GET_USERS。 你的sagas 看起来像这样:

    export function* getUsers$() {
      try {
        const users = yield getUsersAPI();
        yield put(actions.getUsersSuccess(users.data));
      } catch (error) {
        yield put(actions.getUsersFail(error));
      }
    }
    
    export default function* () {
      yield all([takeLatest(actions.GET_USERS, getUsers$)]);
    }
    

    这应该可以解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-15
      • 1970-01-01
      • 2018-12-11
      • 2017-05-30
      • 2017-09-20
      • 2021-01-16
      • 2019-02-21
      • 2021-05-15
      相关资源
      最近更新 更多