Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何确保在导航到另一个页面之前完成reducer响应操作?_Javascript_Reactjs_React Native_Redux Saga - Fatal编程技术网

Javascript 如何确保在导航到另一个页面之前完成reducer响应操作?

Javascript 如何确保在导航到另一个页面之前完成reducer响应操作?,javascript,reactjs,react-native,redux-saga,Javascript,Reactjs,React Native,Redux Saga,我目前正在使用React Native的Redux Saga,我有一个问题,那就是如何正确处理reducer操作没有完成的情况,即在我导航到另一个页面之前触发成功或失败操作。在导航到另一个页面之前,我需要等待直到启动成功或失败操作,但它仍然可以导航 我设置了我的代码,以便它在导航之前检查加载或错误状态,但导航仍然会发生。我认为这是因为updateItems是异步的,并且在响应返回之前,正在进行的代码执行得非常快,例如,如果我确实收到错误,页面将导航而不是等待,以便我可以在页面上显示错误 我想这可

我目前正在使用React Native的Redux Saga,我有一个问题,那就是如何正确处理reducer操作没有完成的情况,即在我导航到另一个页面之前触发成功或失败操作。在导航到另一个页面之前,我需要等待直到启动成功或失败操作,但它仍然可以导航

我设置了我的代码,以便它在导航之前检查加载或错误状态,但导航仍然会发生。我认为这是因为updateItems是异步的,并且在响应返回之前,正在进行的代码执行得非常快,例如,如果我确实收到错误,页面将导航而不是等待,以便我可以在页面上显示错误

我想这可能与我需要在减速机中添加的东西有关,但我不确定

这里是我点击的触发reducer调用的方法,导航很好

updateItems = () => {
    const { code } = this.state;
    const { loading, error } = this.props;
    const id = this.props.navigation.state.params.id;

    this.props.updateItems({
      id: id,
      code: code,
    });

    if (!loading && !error) {
      this.props.navigation.navigate("newPage");
    }
  };
这是减速器本身:

const UPDATE_ITEMS_REQUEST = "UPDATE_ITEMS_REQUEST";
const UPDATE_ITEMS_SUCCESS = "UPDATE_ITEMS_SUCCESS";
const UPDATE_ITEMS_FAILURE = "UPDATE_ITEMS_FAILURE";

export default (itemsReducer = (
  state = {
    data: {
      items: {},
    },
    error: null,
    loading: false,
  },
  { type, payload },
) => {
  switch (type) {
    case UPDATE_ITEMS_REQUEST:
      return Object.assign({}, state, { loading: true, error: null });
    case UPDATE_ITEMS_FAILURE:
      return Object.assign({}, state, { loading: false, error: payload });
    case UPDATE_ITEMS_SUCCESS:
      return {
        loading: false,
        error: null,
        data: payload,
      };
    default:
      return state;
  }
});

export function updateItems(payload) {
  return { type: UPDATE_ITEMS_REQUEST, payload };
}

export function updateItemsFailure(payload) {
  return { type: UPDATE_ITEMS_FAILURE, payload };
}

export function updateItemsSuccess(payload) {
  return { type: UPDATE_ITEMS_SUCCESS, payload };
}


function* updateItemsSaga(payload) {
  const response = yield call(putItems, payload);
  if (response.ok) {
    yield put(updateItemsSuccess(payload));
  } else {
    yield put(
      updateItemsFailure("There has been an error"),
    );
  }
}

export function* watchUpdateItems() {
  yield takeLatest(UPDATE_ITEMS_REQUEST, updateItemsSaga);
}

// API
const putItems = async payload => {
  const res = await fetch(
    `${env.url}/updateItems`,
    {
      method: "PUT",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        id: payload.payload.id,
        code: payload.payload.code,
      }),
    },
  );

  if (!res.ok)
    return {
      status: res.status,
      ok: false,
    };

  const response = await res.json();
  response.status = res.status;
  response.ok = res.ok;
  return response;
};
  • 您可以使用react路由器useHistory将用户重定向到redux操作中的新路由
  • 您可以添加一个标志并将其设置为true作为响应

  • 问题似乎位于
    updateItems
    中。它有一个内部作用域,具有两个属性
    {loading,error}
    。由于这不是一个生成器函数,一旦该函数开始执行,就会触发一个动作
    updateItems
    (这很好),紧接着导航就会发生,因为函数会检查
    {loading,error}
    (相应地
    false
    &
    null

    解决方案可以使用
    updateItemsSaga
    中的导航部分,如下所示:

    function* updateItemsSaga(payload) {
      const response = yield call(putItems, payload);
      if (response.ok) {
        yield put(updateItemsSuccess(payload));
        this.props.navigation.navigate("newPage");
      } else {
        yield put(
          updateItemsFailure("There has been an error"),
        );
      }
    }
    
    或者,您可以从
    updateItems
    中提取条件,并将其用于组件本身:

    const OldPage = ({ loading, error }) => {
    
        if (loading) {
            return <div>Loading... </div>
        } else if(error) {
            return <ErrorPage status="404">;
        } else {
            return <NewPage>;
        }
    
    };
    
    constoldpage=({loading,error})=>{
    如果(装载){
    返回加载。。。
    }else if(错误){
    返回;
    }否则{
    返回;
    }
    };
    

    在项目成功更新之前,两者都应停止导航。希望有帮助

    ,但我只想通过单击旧页面上的按钮导航到新页面。后一个流程不起作用,我不想显示错误页面,而是显示在页面本身上的错误消息。如果我使用第一种方法,我的reducer/saga如何知道这个.props.navigation@jank@Euridice01-我需要更多关于导航道具的信息,如果它是一个动作,那么你可以在传奇中发布它。如果它是一个来自模块的函数,那么您也可以在传奇中导入并使用它。让我知道:)