Javascript 在react redux应用程序中,异步操作的当前状态等内容应该存储在哪里?

Javascript 在react redux应用程序中,异步操作的当前状态等内容应该存储在哪里?,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我有一个登录弹出窗口,它将“IsLogging”布尔值映射到redux存储。当发送登录请求操作时,saga截获该操作并发送登录正在处理的另一个操作,reducer将接收该操作并将“IsLoggin”布尔值设置为true 我的商店: export interface AppState { playerToken:string, loginOpen: boolean, loginProcessing: boolean } 登录传奇: function* loginUser(acti

我有一个登录弹出窗口,它将“IsLogging”布尔值映射到redux存储。当发送登录请求操作时,saga截获该操作并发送登录正在处理的另一个操作,reducer将接收该操作并将“IsLoggin”布尔值设置为true

我的商店:

export interface AppState {
  playerToken:string,  
  loginOpen: boolean,
  loginProcessing: boolean
}
登录传奇:

function* loginUser(action: any) {
  yield put({ type: (LOGIN + PROCESSING) });

  try {
    const response = yield call(apiCall, 'api/token', 'POST', { username: action.payload.username, password: action.payload.password });

   if (response) 
   {
      yield put({ type: (LOGIN + SUCCESS), payload: response.data });
  }
  catch ({ statusCode }) {
    if (statusCode === 401) {
      yield put({ type: (LOGIN + FAIL), payload: { error: "Invalid username or password" } })
    }
    console.log(statusCode);
  }
}
一旦登录完成,如果出现错误,它将发送一个操作,reducer将该操作设置为存储中的“loginError”字符串,并将isLoggingIn设置为false,否则IsLogging设置为false,并设置用户登录id,提示弹出窗口隐藏自身(即isVisible={this.props.playerToken==undefined)

这看起来非常复杂,但我不确定如何使用Redux原则来解决这一问题。我强烈认为iProcessingLogin应该是组件状态的一部分,但组件在发送登录尝试事件后不知道发生了什么,除非它正在侦听组件状态中的某些内容,否则它永远无法知道他是道具

由于需要执行各种crud操作,以及必须在存储中设置为true/false并在组件中正确映射的各种“isCreatingXModel”布尔值,情况变得更糟

redux应该是这样工作的,还是我在它不属于的地方过度使用了它


如果这就是redux应该被使用的方式,那么它到底有什么好处呢?我在网上读了很多有意义的东西,比如说有一个单一的真理点,但是它们都可以在没有疯狂的redux膨胀的情况下完成,我读到有人说在需要之前不要使用redux,但这意味着我将在两个概念上进行api调用当我“需要”的时候集成redux时,分离代码区域。最后,我看到倡导者声称的最大优势之一是它能够及时倒带和向前移动,这很好,但它不会在任何连接到后端数据库的实时应用程序中工作,除非倒带过程中有一个撤销操作api调用操作。

请记住,这些都是我的观点

1.您可能不需要sagas(或thunk或其他“异步”redux插件) 请记住,redux只是状态管理。API调用可以使用普通javascript编写,可以使用redux,也可以不使用redux。例如:下面是不使用sagas的流的基本复制:

e、 g

注意
store.dispatch
的用法。React-Redux中有一个有趣的概念,即您只能使用mapDispatchToProps来分派操作,但幸运的是,事实并非如此

我将您的多个操作替换为一个具有状态和可选数据的操作。这将减少您需要编写的操作和还原程序的数量,但您的操作历史记录将更难读取。(您将只有一个操作,而不是三个不同的操作。)

2.您可能不需要redux。 如果不使用redux,上面的示例函数可能看起来基本相同——想象一下用
this.setState
调用替换
store.dispatch
调用。将来,当您添加它时,您仍然需要编写所有的reducer、action、action creator样板文件,但这只会比以前稍微痛苦一些我从一开始就喜欢它

正如我上面所说的,在使用React时,我通常使用Redux,因为内置的状态管理对于任何类型的大型应用程序都有一个糟糕的心理地图

有两条相反的经验法则:

  • 对组件之间需要共享的状态使用redux
  • 对所有状态使用redux,并获得一个单一真相来源

  • 我倾向于第二个。我讨厌在大型React组件树的叶子中寻找错误的状态。这肯定是一个没有“正确”答案的问题。

    对于我的redux还原程序,我通常有一个state.status字符串,其中包含“loading”或“failed”之类的内容所以我有一个清晰的单一实体,它输出减速器的状态。如果你的状态很容易区分,它工作得很好。
    import { setLoadingStatus } from './actions'
    import { store } from './reducers' // this is what is returned by a createStore call
    
    export function myApiCall(myUrl, fetchOptions) {
      store.dispatch(setLoadingStatus('loading'))
    
      return fetch(myUrl, fetchOptions)
        .then((response) => {
          store.dispatch(setLoadingStatus('succeeded', data))
          // do stuff with response data (maybe dispatch a different action to use it?)
        })
        .catch((error) => {
          store.dispatch(setLoadingStatus('failed', error))
          // do stuff 
        })
    }