【问题标题】:How to pass internal state to global state using Redux如何使用 Redux 将内部状态传递给全局状态
【发布时间】:2018-04-04 04:03:37
【问题描述】:

我第一次在应用程序中使用 Redux,并且无法理解如何将组件内部状态传递给全局状态对象。

`export default class ComponentOne extends Component {
   constructor() {

     this.state = {
       number: 0
     }

     handleNumber = (e) => {
       this.setState({
         number: e.target.value 
       })
     }

     render() {
       console.log(this.state.number)
       return (
         <div> 
          <input onChange={this.handleNumber} type="number"> 
         </div> 
       )
     }
   }
}

function mapStateToProps(state) {
  return {
    number: state
  }
}

export default connect(mapStateToProps, { HANDLE_NUMBER_CHANGE })(ComponentOne);`

我的动作和减速器:

`const HANDLE_NUMBER_CHANGE = state => {
  return {
    type: 'HANDLE_NUMBER_CHANGE'
  }
}

export default (state = 0, action) {
  switch(action.type) {
    case 'HANDLE_NUMBER_CHANGE': 
      //Im lost here - trying to save internal state 
    default: 
      return state; 
  }
}`

我的商店设置正确,中间件使用 redux-thunk。 当我记录 store.getState() - 无论我的组件内部状态如何,它都会记录 0。 任何人都可以解释这是如何工作的吗?

提前致谢!

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

    当您拥有全局状态时,您不需要将其保存到本地状态。组件可以通过 this.props.value 访问它。

    设置全局状态的方法是将值传递给动作创建者,动作创建者在动作中返回它。 reducer 在 action 对象中获取它并保存它。

    有许多简单的示例可用。这里是one

    这是更改后的代码: (我没有运行它 - 可能会有错误,但我相信您将能够自己修复它们;我已经将代码分成了几个文件 - 这通常是如何完成的。查看示例如果您有问题,请点击上面的链接)

    // file:  src/components/ComponentOne.js
    
    import React from 'react';
    import { connect } from 'react-redux';
    import { handleNumber } from '../actions';
    
    class ComponentOne extends Component {
    
      constructor(props) {
         super(props);
         this.handleNumber = this.handleNumber.bind(this);
      }
    
      render() {
        console.log(this.state.number)
        return (
         <div> 
          <input onChange={(e) => this.props.handleNumber(e.target.value)} type="number" /> 
         </div> 
       );
      }
    }
    
    function mapStateToProps(state) {
      return {
        number: state
      }
    }
    
    export default connect(mapStateToProps, { handleNumber })(ComponentOne);
    
    // end of file
    
    /// separate file:   src/reducers/index.js ////
    
    import { combineReducers } from 'redux';
    import dataReducer from './dataReducer';
    
    export default combineReducers({
      number: dataReducer
    });
    
    // end of file
    
    // separate file:   src/reducers/dataReducer.js
    const DataReducer = (state = 0, action) => {
      switch(action.type) {
        case 'HANDLE_NUMBER_CHANGE': 
          return action.payload; 
        default: 
          return state; 
      }
    };
    
    export default DataReducer;
    // end of file
    
    // separate file:   src/actions/index.js
    export function handleNumber(value) {
      return ({
        type: 'HANDLE_NUMBER_CHANGE',
        payload: value
      });
    }
    

    【讨论】:

    • 感谢您的回复!当我摆脱本地状态并将值传递给操作时 - 由于减速器中的初始状态设置为 0,我仍然得到 0。如何更新此状态?
    • 查看更新后的代码。阅读说明,可能还有一些工作留给你:)
    【解决方案2】:

    我看不出让你的内部状态等于你的商店的逻辑。我不是说你错了,但它似乎不适合 redux 范式。不过……

    行动应该是……

    export function HANDLE_NUMBER_CHANGE = number => {
      return {
        type: 'HANDLE_NUMBER_CHANGE'
        payload: number
      }
    }
    

    Reducer 应该看起来像...

    export default (state = {number: 0}, action) {
      switch(action.type) {
        case 'HANDLE_NUMBER_CHANGE': 
            return (state = {
                ...state,
                number: action.payload,
    });
    

    最后,您需要从 onChange 函数调用调度。

      dispatch(HANDLE_NUMBER_CHANGE(e.target.value).
    

    如果不将值传递给 action,reducer 就无法将其添加到 store。

    【讨论】:

      【解决方案3】:

      如果您正在使用 redux 管理您的 ComponentOne 状态,那么您不需要 反应状态。

      组件一

      export default class ComponentOne extends Component {
         constructor() {
      
           handleNumber = (e) => {
             this.props.updateNumber(e.target.value);//call dispatch method
           }
      
           render() {
             return (
               <div> 
                <input onChange={this.handleNumber} type="number"> 
               </div> 
             )
           }
         }
      }
      
      
      function mapStateToProps(state) {
        return {
          number: state.number //map updated number here
        }
      }
      
      
      function mapDispatchToProps(state) {
        return {
          updateNumber(number){
              dispatch({type: 'HANDLE_NUMBER_CHANGE',number});//dispatch action
          }
        }
      }
      export default connect(mapStateToProps, mapDispatchToProps)(ComponentOne);
      

      减速器:

      export default (state = 0, action) {
        switch(action.type) {
          case 'HANDLE_NUMBER_CHANGE': 
            return {
                ...state,number : actio.number//update number here
            }
          default: 
            return state; 
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-17
        • 2020-10-29
        • 2019-03-18
        • 1970-01-01
        • 2016-01-19
        • 2017-01-26
        • 1970-01-01
        • 2019-12-05
        相关资源
        最近更新 更多