React / Redux - 保存选择值onChange [英] React/Redux - save select value onChange

查看:79
本文介绍了React / Redux - 保存选择值onChange的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个Component,允许您添加/删除下拉字段(onClick of two buttons)。我正在使用Redux来保持下拉状态,以便当我来回导航(React Router)时,添加的下拉列表不会丢失。

I've created a Component that lets you Add/Remove a dropdown fields (onClick of two buttons). I'm using Redux to keep the state of the dropdown so that when I navigate back and forth (React Router) the added dropdowns are not lost.

现在我还需要保持每个下拉列表的值更改。所以onChange我将下拉列表的值发送给reducer,但它似乎一次更新所有下拉列表(不是单独的)。

Now I also need to keep the values of each dropdown onChange. So onChange I'm sending the value of the dropdowns to the reducer but it seems to be updating all the dropdowns at once (not individually).

知道如何解决这个问题吗?

Any idea how to fix this?

这是我到目前为止的代码:

Here is my code so far:

组件

import React from 'react'
import { connect } from 'react-redux'
import uuidV4 from 'uuid-v4'
import { saveSelect, removeSelect, saveSelectValue, incrementCounter, decrementCounter } from '../actions.js'


class AccountUpgrade extends React.Component {
  constructor(props) {
    super(props);
  }

  addInput = (counter) => {
    this.props.saveSelect(uuidV4())
    this.props.incrementCounter(counter)
  }

  removeInput = (index, counter) => {
    this.props.removeSelect(index)
    this.props.decrementCounter(counter)
  }

  saveSelectValue = (e) => {
    let data = {}
    data = e.target.value

    this.props.saveSelectValue(data)
  }

  renderSelect = (id, index) => {
    const selectedValue = this.props.selectedValue || ''
    const counter = this.props.counter

    return(
      <div className="col-12">
        <select
          key={id}
          name={'document-'+ id}
          value={selectedValue}
          onChange = {this.saveSelectValue}
        >
          <option value="0">Please Select</option>
          <option value="1">Australia</option>
          <option value="2">France</option>
          <option value="3">United Kingdom</option>
          <option value="4">United States</option>
        </select>

        <button onClick={ () => {this.removeInput(index, counter) }}>Remove</button>
      </div>
    )
  }

  render(){
    const ids = this.props.ids || []
    const counter = this.props.counter

    return (
      <div>

        {this.props.counter <= 4 &&
          <button onClick={ this.addInput }>Add</button>
        }

        <div className="inputs">
          {ids.map(this.renderSelect)}
        </div>
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    store: state.EligibleAbout,
    ids: state.EligibleAbout.ids,
    selectedValue: state.EligibleAbout.selectedValue,
    counter: state.EligibleAbout.counter,
  }
}

const EligibleAbout = connect(mapStateToProps, {saveSelect, removeSelect, saveSelectValue, incrementCounter, decrementCounter})(AccountUpgrade)

export default EligibleAbout

action.js

export const ADD_SELECT = 'ADD_SELECT'
export const REMOVE_SELECT = 'REMOVE_SELECT'
export const SAVE_SELECT_OPTION = 'SAVE_SELECT_OPTION'
export const INCREMENT_COUNTER = 'INCREMENT_COUNTER'
export const DECREMENT_COUNTER = 'DECREMENT_COUNTER'

export function saveSelect(data) {
  return { type: ADD_SELECT, data }
}

export function removeSelect(data) {
  return { type: REMOVE_SELECT, data }
}

export function saveSelectValue(data) {
  return { type: SAVE_SELECT_OPTION, data}
}

export function incrementCounter(data) {
    return { type: INCREMENT_COUNTER, data }
}

export function decrementCounter(data) {
    return { type: DECREMENT_COUNTER, data }
}

reducer.js

import { combineReducers } from 'redux'
import { ADD_SELECT, REMOVE_SELECT, SAVE_SELECT_OPTION } from './actions'

function EligibleAbout(state = { ids: [], counter: 0, selectedValue: 'Please select'}, action = {}){
  switch (action.type){
    case ADD_SELECT:
      return {
        ...state,
        ids: [].concat(state.ids, action.data),
      }
    case REMOVE_SELECT:
      return {
        ...state,
        ids: state.ids.filter((id, index) => (index !== action.data)),
      }
    case SAVE_SELECT_OPTION:
      return {
        ...state,
        selectedValue: action.data
      }
    case INCREMENT_COUNTER:
      return {
        ...state,
        counter: state.counter + 1
      }
    case DECREMENT_COUNTER:
      return {
        ...state,
        counter: state.counter - 1
      }
    default:
      return state
  }
}

const FormApp = combineReducers({
  EligibleAbout
})

export default FormApp


推荐答案

由于您需要为每个id或下拉列表保留选定的值,因此最好的方法是保持带有对象的对象数组其中 id 属性而不是字符串数组 ids 。因此,您必须将代码更改为类似的内容。我没有测试代码,所以如果你遇到任何问题,请在评论中告诉我。

Since you need to keep the selected value for each id or dropdown, the best approach would be keeping an object array with objects which have id and value property instead of having string array ids. So you will have to change your code into something like this. I didn't test the code, so let me know in comments if you get any issue with it.

class AccountUpgrade extends React.Component {
  constructor(props) {
    super(props);
  }

  addInput = () => {
    this.props.saveSelect({id:uuidV4()})
  }

  removeInput = (index) => {
    this.props.removeSelect(index)
  }

  saveSelectValue = (e, id) => {
    let data = {}
    data.id = id;
    data.value = e.target.value

    this.props.saveSelectValue(data)
  }

  renderSelect = (selection, index) => {
    const selectedValue = selection.value || '';
    const id = selection.id;

    return(
      <div className="col-12">
        <select
          key={id}
          name={'document-'+ id}
          value={selectedValue}
          onChange = {(e) => this.saveSelectValue(e, id)}
        >
          <option value="0">Please Select</option>
          <option value="1">Australia</option>
          <option value="2">France</option>
          <option value="3">United Kingdom</option>
          <option value="4">United States</option>
        </select>

        <button onClick={ () => {this.removeInput(index) }}>Remove</button>
      </div>
    )
  }

  render(){
    const selections = this.props.selections || []

    return (
      <div>
        <button onClick={ this.addInput }>Add</button>

        <div className="inputs">
          {selections.map(this.renderSelect)}
        </div>
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    store: state.EligibleAbout,
    selections: state.EligibleAbout.selections,
  }
}

您还需要修改减速机。

function EligibleAbout(state = { selections: [] } , action = {}){
  switch (action.type){
    case ADD_SELECT:
      return {
        ...state,
        selections: [].concat(state.selections, action.data),
      }
    case REMOVE_SELECT:
      return {
        ...state,
        selections: state.selections.filter((selection, index) => (index !== action.data)),
      }
    case SAVE_SELECT_OPTION:
      return {
        ...state,
        selections: state.selections.map((selection) => selection.id === action.data.id ? action.data : selection)
      }
    default:
      return state
  }
}

这篇关于React / Redux - 保存选择值onChange的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆