状态未通过 redux 正确传递

State is not passing correctly with redux

嘿,我有两个表单,我想分别保持状态,我添加了 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);

提前致谢:)

您似乎在尝试将输入更改事件直接合并到 redux 状态中。这不是它的工作原理。

您可以使用 event.target 访问从 change 事件更改的 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 中。