根据onChange事件值更改Redux状态

时间:2019-12-12 08:20:49

标签: redux

我正在使用redux,并且我的状态为空字符串值。每个空键都必须使用输入onChange事件来填写。假设我要更改“ business_selected”键,该函数应该是什么样?这是我的状态:


const initialState = {

        user: {},
        applications: [
            {
                companyFlow: {
                    stage1: {
                        business_activity: "",
                        business_selected: ""
                    },

                    stage2: {
                        legal_name: "",
                        registration_number: "",
                        business_website: "",
                        incorporation_date_text: "",
                        legal_form: ""
                    }
                }
            }
        ]
};

export default function changeInput(state = initialState, action) {
  switch (action.type) {
    case CHANGE_INPUT:
      return {
        // ??????
      };
    default:
      return state;
  }
}

3 个答案:

答案 0 :(得分:1)

onChnage值应以本地状态而不是Redux状态存储。 理想情况下,仅全局值应以redux状态存储。

答案 1 :(得分:1)

除了对深层嵌套的状态变量(避免使用recommended)的担忧外,如果在最基本的层面上要求的是如何全局访问这些变量,则理所当然要将调度某些动作绑定到组件事件(例如onChangeonKeyUp等属性),我建议参考该主题的official tutorial

但是,以下示例非常简单,说明了一般概念。您可以自行决定在状态复杂度和组件灵活性之间进行缩放,重新平衡。

//dependencies
const { render } = ReactDOM,
      { createStore } = Redux,
      { connect, Provider } = ReactRedux
      
//store initialization
const defaultState = {
        businessActivity: {
          options: ['operation', 'investing', 'financing'],
          currentValue: ''
        },
        legalName:{
          currentValue:''
        }
      },
      appReducer = (state=defaultState, action) => {
        switch(action.type){
          case 'SET_PARAM': {
            const {payload:{param,val}} = action           
            return {...state, [param]:{...state[param], currentValue: val}}
          }
          default: return state
        }     
      },
      store = createStore(appReducer) 
//arbitrary dropdown component
const DropDown = ({onParamChange, param, options, val}) => (
  <select 
    param={param} 
    onChange={e => (val=e.target.value, onParamChange(param,val))}
  >
    {['',...options].map((opt,key) => <option value={opt} key={key} selected={opt==val}>{opt}</option>)}
  </select>
)
//dropdown container
var mapStateToProps = (state, {param}) => ({
        val:state[param]['currentValue']||'',
        options:[...state[param]['options']]
      }),
      mapDispatchToProps = (dispatch, {param,val}) => ({onParamChange: (param,val) => dispatch({type:'SET_PARAM',payload:{param,val}})})
const DropDownContainer = connect(mapStateToProps, mapDispatchToProps)(DropDown)
//arbitrary input component
const InputBox = ({onParamInput, param, val}) => (
  <input 
    param={param} 
    val={val}
    placeholder={val}
    onKeyUp={e => (val=e.target.value, onParamInput(param,val))}
  ></input>
)
//input box container
var mapStateToProps = (state, {param}) => ({val: state[param]['currentValue']||''}),
      mapDispatchToProps = (dispatch, {param,val}) => ({onParamInput: (param,val) => dispatch({type:'SET_PARAM', payload:{param,val}})})
const InputBoxContainer = connect(mapStateToProps,mapDispatchToProps)(InputBox)
//resulting state mirror
const PrintOut = ({activity,name}) => <div>Current business activity is {activity||'_'} and legal name is {name||'_'}</div>
//print out container
var mapStateToProps = ({businessActivity:{currentValue:activity},legalName:{currentValue:name}}) => ({activity,name})
const PrintOutContainer = connect(mapStateToProps)(PrintOut)
//provider
render(
  <Provider store={store}>
    <DropDownContainer param="businessActivity" />
    <InputBoxContainer param="legalName" />
    <PrintOutContainer />
  </Provider>,
  document.getElementById('root')
)
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script><script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script><script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.4/redux.min.js"></script><script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.1.1/react-redux.min.js"></script><div id="root"></div>

答案 2 :(得分:0)

通常,onChange是使用component本身的本地状态来处理的,但是如果您想在redux中进行处理,则可以这样做。

export default function changeInput(state = initialState, action) {
  switch (action.type) {
    case CHANGE_INPUT:
      return {
       ...state,
       applications: state.applications.map(application => {
        return Object.assign({}, application, {
         ...application,
         companyFlow: {
          ...application.companyFlow,
          stage1: {
            ...application.companyFlow.stage1,
            business_selected: action.payload
          }
         }
        }
       return application
      });
    default:
      return state;
  }
}