状态无法通过Redux正确传递

时间:2020-05-20 07:39:33

标签: reactjs redux react-redux react-state-management

嘿,我有两种形式想分别保持状态,我添加了redux并添加了reducer来保持状态改变,但是我的问题是,当我改变表单状态时,它也会添加到其他表单状态中我想分别保持每个状态enter image description here

就像您在图片中看到的那样,当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);

预先感谢:)

1 个答案:

答案 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)也可以正常工作。