Redux 开发工具状态图显示reducer 正在更新另一个reducer

Posted

技术标签:

【中文标题】Redux 开发工具状态图显示reducer 正在更新另一个reducer【英文标题】:Redux dev tool state chart shows that reducer is updating another reducer 【发布时间】:2018-01-02 01:58:16 【问题描述】:

我已经实现了一个简单的计数器减速器,它具有“增量”、“减量”等操作。我有“保存”操作,应该将当前计数器值保存在数组中。

我还实现了另一个 reducer,它应该在加载时获取一些数据并将其保存到数组中。

当我向 counter reducer 发送“保存”操作时,Redux Dev 工具状态图显示 fetch reducer 也在更新。它没有改变 fetch reducer 的任何值,但图表显示了奇怪的行为。

我可能对如何使用 fetch reducer 或两者都有错误。

App.js(容器组件)

    import React,  Component  from 'react';
    import  connect  from 'react-redux'
    import logo from './logo.svg';
    import './App.css';
    import Counter from './components/Counter'
    import Data from './components/Data'
    import 
      increaseAction,
      decreaseAction,
      resetAction,
      saveAction,
      removeAction,
      fetchData
     from './actions'

    class App extends Component 
      componentDidMount() 
        // the only thing i dispatch to fetch reducer
        const response = [1,2,3,4,5,6,7,8]
        this.props.fetchData(response);
      
      render() 
        return (
          <div className="App">
            <div className="App-header">
              <img src=logo className="App-logo"  />
              <h2>Welcome to React</h2>
            </div>
            <p className="App-intro">
              To get started, edit <code>src/App.js</code> and save to reload.
            </p>
            <Counter
              onIncreaseClick=this.props.onIncreaseClick
              onDecreaseClick=this.props.onDecreaseClick
              onResetClick=this.props.onResetClick
              onSaveClick=this.props.onSaveClick
              onRemoveClick=this.props.onRemoveClick
              value=this.props.counterValue
              savedCounter=this.props.savedCounter
            />
            <Data data=this.props.fetch/>
          </div>
        );
      
    

  // Map Redux state to component props
  function mapStateToProps(state)  
    let counter = state.counter
    let fetch = state.fetch
    return 
      counterValue: counter.count,
      savedCounter: counter.saved,
      fetch: fetch.data
    ;
  

  // Map Redux actions to component props
  function mapDispatchToProps(dispatch) 
    return 
      onIncreaseClick: () => dispatch(increaseAction),
      onDecreaseClick: () => dispatch(decreaseAction),
      onResetClick: () => dispatch(resetAction),
      onSaveClick: () => dispatch(saveAction),
      onRemoveClick: () => dispatch(removeAction),
      fetchData: (data) => dispatch(fetchData(data))
    ;
  

  export default connect(mapStateToProps, mapDispatchToProps)(App)

这是我的减速器(它们在单独的文件中)

    // Reducer:
    function counter(state=count: 0, saved: [], action) 
      let count = state.count;
      let saved = state.saved;
      switch(action.type)
        case 'increase':
          return 
            ...state,
            count: count  + 1
          ;
        case 'decrease':
          if (count === 0) 
            return ...state, count: count 
          
          return 
            ...state,
            count: count - 1
          ;
        case 'reset':
          return 
            ...state,
            count: count  = 0
          ;
        case 'save':
          return 
            ...state,
            saved: [...saved, count]
          ;
        case 'remove':
          return 
            ...state,
            saved: [...saved.slice(0, -1)]
          ;
        default:
          return state;
      
    

    export default counter

    // Reducer:
    function fetch(state=data: [], action) 
      console.log("When I call 'save' this is also invoked");
      switch(action.type)
        case 'fetch':
        return ...state, data: [...action.payload] 
        default:
          return state;
      
    

    export default fetch

动作:

    export const increaseAction = type: 'increase';
    export const decreaseAction = type: 'decrease';
    export const resetAction = type: 'reset';
    export const saveAction = type: 'save';
    export const removeAction = type: 'remove';
    export const FETCH_DATA = 'fetch';

    export function fetchData(payload) 
      return 
        type: FETCH_DATA,
        payload: payload,
      
    

我如何创建我的商店(请注意,为简单起见,此逻辑都位于 index.js 中):

    // Combine all application reducers
    const appStore = combineReducers(
      counter,
      fetch
    )


    // Store configuration
    const loggerMiddleware = createLogger()
    let store = createStore(
      appStore,
      // only for dev
      window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
      applyMiddleware(
        loggerMiddleware
      )
    )

查看视频中的问题所在: https://youtu.be/oKOkU_VjZ7E

试试看: https://github.com/kdichev/personal-portfolio/tree/feature/add-create-redux-react-app

【问题讨论】:

【参考方案1】:

当您调度任何操作时,所有减速器都会被调用,这是设计使然。

【讨论】:

这是正常行为吗?看看我发布的视频,它只是不感觉对吗?! 是的,在任何调度的操作上调用所有减速器是正常行为。您的减速器似乎没有任何问题。

以上是关于Redux 开发工具状态图显示reducer 正在更新另一个reducer的主要内容,如果未能解决你的问题,请参考以下文章

使用 Redux 工具包的常见加载状态 reducer

Redux Toolkit:状态在 reducer 中显示为 Proxy / undefined

Redux reducers——改变深度嵌套状态

Redux 状态未在 reducer 中按预期构建

Redux (with React) Reducer switch 语句不更新状态

Redux 状态未在开发工具中更新,但当前状态正在反映在道具中