嘿,我有两种形式想分别保持状态,我添加了redux并添加了reducer来保持状态改变,但是我的问题是,当我改变表单状态时,它也会添加到其他表单状态中我想分别保持每个状态
就像您在图片中看到的那样,当newProjectForm只需要位于屋顶窗体时,替换属性已被添加到其中。
我在表单上有相同的化简器,因为我只需要跟踪onInputChange。
这是我的两种形式: 第一种形式:
import React from 'react'
import {Form, FormGroup, ControlLabel, FormControl, HelpBlock, Button, ButtonToolbar,
Toggle } from 'rsuite';
import InputPicker from '../input-picker';
import './form.css'
import {onInputChanged} from '../../redux/actions/form.actions';
import { connect } from 'react-redux';
//onChange = {props.onInputChanged} formValue = {props.newProjectForm}
const options = ["yes","no"];
function NewProjectForm(props){
return (
<Form className='form' layout="horizontal" >
<h1 className='title'>New Project</h1>
<br/>
<FormGroup>
<ControlLabel>Address</ControlLabel>
<FormControl name="address" />
<HelpBlock tooltip>Required</HelpBlock>
</FormGroup>
<FormGroup>
<ControlLabel>Affilate</ControlLabel>
<InputPicker name="affilate" data ={options} onChange={props.onInputChanged} style={{width:'300px'}}/>
<HelpBlock tooltip>Required</HelpBlock>
</FormGroup>
<FormGroup>
<ControlLabel>Size</ControlLabel>
<FormControl name="size" type="number" />
</FormGroup>
<FormGroup>
<ControlLabel>Bedroom Amount</ControlLabel>
<FormControl name="bedrooms" type="number" />
</FormGroup>
<FormGroup>
<ControlLabel>Bathrooms amount</ControlLabel>
<FormControl name="bathrooms" type="number" />
</FormGroup>
<FormGroup>
<ControlLabel>Stories</ControlLabel>
<FormControl name="stories" type="number" />
</FormGroup>
<FormGroup>
<ControlLabel>Has Gas</ControlLabel>
<Toggle name="gas"/>
</FormGroup>
<FormGroup>
<ButtonToolbar>
<Button appearance="primary">Save</Button>
<Button appearance="default">Discard</Button>
</ButtonToolbar>
</FormGroup>
</Form>
);
}
const mapStateToProps = (state) => {
return {
newProjectForm: state.newProjectForm
}
};
const mapDispatchToProps = (dispatch) => {
return {
onInputChanged: (event) => dispatch(onInputChanged(event))
}
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(NewProjectForm);
第二种形式:
import React from 'react'
import {Form, FormGroup, ControlLabel, FormControl, HelpBlock, Button, ButtonToolbar} from 'rsuite';
import './form.css'
import {onInputChanged} from '../../redux/actions/form.actions';
import { connect } from 'react-redux';
import InputPicker from '../input-picker';
function RoofForm(props){
//replace all-roof type description color
const options = ["yes","no"];
// console.log(props);
//onChange={props.onInputChanged}
return (
<Form className='form' layout="horizontal" onChange = {props.onInputChanged} formValue = {props.roofForm}>
<h1 className='title'>Roof</h1>
<br/>
<FormGroup>
<ControlLabel>Replace ?</ControlLabel>
<InputPicker name="replace" style={{ width: 300 }} data={options} onChange={props.onInputChanged}/>
<HelpBlock tooltip>Required</HelpBlock>
</FormGroup>
<FormGroup>
<ControlLabel>All Roof?</ControlLabel>
<InputPicker name="all-roof" style={{ width: 300 }} data={options} onChange={props.onInputChanged}/>
<HelpBlock tooltip>Required</HelpBlock>
</FormGroup>
{props.roofForm['all-roof'] === 'yes' && (<div><FormGroup>
<ControlLabel>Type</ControlLabel>
<InputPicker name="type" style={{ width: 300 }} />
</FormGroup>
<FormGroup>
<ControlLabel>Description</ControlLabel>
<InputPicker name="description" style={{ width: 300 }} />
</FormGroup>
{props.roofForm.type === 'shingles' && <FormGroup>
<ControlLabel>Color</ControlLabel>
<InputPicker name="color" style={{ width: 300 }} />
</FormGroup>}
</div>)
}
<FormGroup>
<ControlLabel>Rain diverter</ControlLabel>
<FormControl name="rain-diverter" type="number" style={{ width: 300 }} />
</FormGroup>
<FormGroup>
<ControlLabel>Drip edge</ControlLabel>
<FormControl name="drip-edge" type="number" style={{ width: 300 }}/>
</FormGroup>
<FormGroup>
<ButtonToolbar>
<Button appearance="primary">Save</Button>
<Button appearance="default">Discard</Button>
</ButtonToolbar>
</FormGroup>
</Form>
);
}
const mapStateToProps = (state) => {
return {
roofForm: state.roofForm
}
};
const mapDispatchToProps = (dispatch) => {
return {
onInputChanged: (event) => dispatch(onInputChanged(event))
}
};
export default connect(
mapStateToProps,
mapDispatchToProps)
(RoofForm);
这是我的redux设置:
Form Actions:
export const ON_INPUT_CHANGED = 'ON_INPUT_CHANGED';
export function onInputChanged(event) {
console.log(event);
return(
{
type: ON_INPUT_CHANGED,
payload: event
}
)
}
这是我的减速器:
import {ON_INPUT_CHANGED} from '../actions/form.actions';
function formReducerWrapper(defaultState){
return (state=defaultState, action) => {
switch(action.type){
case ON_INPUT_CHANGED:
state = {
...state,
...action.payload
}
break;
default:
return state;
}
return state;
}
}
const newProjectDefault = {
affilate: {label:"", value: ""}
}
const roofDefault ={
replace:{label:"",value:""},
"all-roof":{label:"",value:""},
type:{label:"",value:""},
description: {label:"",value:""},
color:{label:"",value:""}
}
export const newProjectReducer = formReducerWrapper(newProjectDefault);
export const roofReducer = formReducerWrapper(roofDefault);
预先感谢:)
答案 0 :(得分:0)
您似乎正在尝试将输入更改事件直接合并到redux状态。那不是它的工作原理。
您可以使用change
访问从event.target
事件更改的HTML输入元素,然后读取最新值event.target.value
。
如果希望表单数据保持独立,则需要为每个表单分派不同的信息。例如:
dispatch({ type: 'input-changed', form: 'newProject', field: 'affiliate', value: event.target.value });
在化简版中,它应该跳过其他事件以其他形式出现。
if (event.form !== 'newProject') return state;
如果变得乏味,可以使用诸如redux-form之类的帮助程序包来帮助构建应用程序以避免重复的代码。将表单数据存储在本地状态(而不是将其放入redux)也可以正常工作。