我创建了一个组件,可以让您添加/删除下拉字段(点击两个按钮)。我使用 Redux 来保持下拉菜单的状态,这样当我来回导航时 (React Router),添加的下拉菜单不会丢失。
现在我还需要保留每个下拉列表的值 onChange。所以 onChange 我将下拉列表的值发送到 reducer ,但它似乎是一次更新所有下拉列表(不是单独更新)。
知道如何解决这个问题吗?
到目前为止,这是我的代码:
组件
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
和 value
属性的对象,而不是具有字符串数组 ids
。因此,您将不得不将代码更改为类似这样的内容。我没有测试代码,所以如果您有任何问题,请在评论中告诉我。
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,
}
}
您还需要修改 reducer 。
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
}
}
关于javascript - React/Redux - 保存选择值 onChange,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44549916/