简体   繁体   中英

How to update state in react-redux?

I have made a submit form. I have made userReducer where user[] is array and each array element has firstname , lastname , emailid etc. When I click on submit button it shows array element [0] but when I click on clear button and again try to fill in the form and try to submit no user is added again ie no state is updated. How to fix this problem ?

Form component (form.js) :

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as action from '../actions/actions';


import './form.css';

class Form extends Component {
    constructor(props) {
    super(props);
    this.setFirstName = this.setFirstName.bind(this);
    this.setLastName = this.setLastName.bind(this);
    this.setEmailId = this.setEmailId.bind(this);
    this.setIban = this.setIban.bind(this);
    this.setBankName = this.setBankName.bind(this);
    this.showUser = this.showUser.bind(this);
    this.reset = this.reset.bind(this);

     console.log(this.props);

    }

    setFirstName(event) {
    this.props.dispatch(action.setFirstName(event.target.value));
    }

    setLastName(event) {
    this.props.dispatch(action.setLastName(event.target.value));
    }

    setEmailId(event) {
    this.props.dispatch(action.setEmailId(event.target.value));
    }

    setIban(event) {
    this.props.dispatch(action.setIban(event.target.value));
    }

    setBankName(event) {
    this.props.dispatch(action.setBankName(event.target.value));
    }

    showUser(){
        const jsonobj = this.props;
        alert(JSON.stringify(jsonobj));
    }

    reset(){
        this.props.dispatch(action.setFirstName(''));
        this.props.dispatch(action.setLastName(''));
        this.props.dispatch(action.setEmailId(''));
        this.props.dispatch(action.setIban(''));
        this.props.dispatch(action.setBankName(''));
    }


  render(){
    return(
      <div>
          <div id="center">
              <form>
                    <div className="form-group">
                         <label htmlFor="firstname">First Name:</label>
                         <input type="firstname" className="form-control" id="firstname" value={this.props.firstname} onChange={this.setFirstName} required/>
                    </div>

                    <div className="form-group">
                         <label htmlFor="lastname">Last Name:</label>
                         <input type="lastname" className="form-control" id="lastname" value={this.props.lastname} onChange={this.setLastName} required/>
                    </div>

                    <div className="form-group">
                        <label htmlFor="email">Email address:</label>
                        <input type="email" className="form-control" id="email" value={this.props.emailid} onChange={this.setEmailId} required/>
                    </div>

                    <div className="form-group">
                         <label htmlFor="bankacc">IBAN:</label>
                         <div id="deletebank" className="items">
                         <input type="bankacc" className="form-control" id="bankacc" value={this.props.iban} onChange={this.setIban} required/>
                         <button type="button" className="btn btn-default btn-sm">
                            <span className="glyphicon glyphicon-trash"></span> 
                         </button>
                         </div>
                    </div>

                    <div className="form-group">
                         <label htmlFor="bankname">Bank Name:</label>
                         <input type="bankname" className="form-control" id="bankname" value={this.props.bankname} onChange={this.setBankName} required/>
                    </div>

                    <div className="form-group">
                        <div id="buttons" className="items">
                            <button type="button" class="btn btn-warning" onClick={this.reset}>Clear Input</button>
                            <button type="button" className="btn btn-success" onClick={this.showUser}>Submit</button>
                        </div>
                    </div>


              </form>
          </div>
      </div>

    )}


}

const mapStateToProps = store => {
  return {
    firstname: store.user.firstname,
    lastname: store.user.lastname,
    emailid: store.user.emailid,
    iban: store.user.iban,
    bankname: store.user.bankname
  }
}

export default connect(mapStateToProps)(Form);

reducer.js:

const userReducer = (state = {
  user:[{
    firstname:'',
    lastname:'',
    emailid:'',
    bankaccounts:{
      iban:'',
      bankname:''
    }
  }]
  }, action) => {

  switch (action.type) {
    case 'SET_FIRSTNAME':{
      return {
        ...state,
        user:{...state.user, firstname: action.payload}
      }
    }

    case 'SET_LASTNAME':{
      return {
        ...state,
        user:{...state.user, lastname: action.payload}
      }
    }

    case 'SET_EMAILID':{
      return {
        ...state,
        user:{...state.user, emailid: action.payload}
      }
    }

    case 'SET_IBAN':{
      return {
        ...state,
        user:{...state.user, iban: action.payload}
      }
    }

    case 'SET_BANKNAME':{
      return {
        ...state,
        user:{...state.user, bankname: action.payload}
      }
    }
    default: return state;
  }

}

export default userReducer;

Actions.js:

export const SET_FIRSTNAME = 'SET_FIRSTNAME';
export const SET_LASTNAME = 'SET_LASTNAME';
export const SET_EMAILID = 'SET_EMAILID';
export const SET_IBAN = 'SET_IBAN';
export const SET_BANKNAME = 'SET_BANKNAME';


export function setFirstName(firstname){
    return {
        type:SET_FIRSTNAME,
        payload:firstname
    }
}

export function setLastName(lastname){
    return {
        type:SET_LASTNAME,
        payload:lastname
    }
}

export function setEmailId(emailid){
    return {
        type:SET_EMAILID,
        payload:emailid
    }
}

export function setIban(iban){
    return {
        type:SET_IBAN,
        payload:iban
    }
}

export function setBankName(bankname){
    return {
        type:SET_BANKNAME,
        payload:bankname
    }
}

store.js:

import { createStore } from 'redux';

import userReducer from './reducers/reducers';


const store = createStore(userReducer);

store.subscribe(() => {
    console.log('Store changed', store.getState());
})

export default store;

Screenshot:

在此处输入图片说明

在此处输入图片说明

There's a bunch of stuff to address here, but the primary issue is that your state is expecting user to be an array. I think it would be very wise to rename this users as to not get confused:

(I'm going to remove some keys to make this easier)

const initialState = {
  users: [ // note "users" not "user"
    {
      firstname: '',
      lastname: '',
    },
  ],
};

Your reducer switch statements don't specify WHICH user it should be updating. If you want to just start with "adding" a new user it might look something like this:

const userReducer = (state = initialState, action) => {
  switch (action.type) {
    case "ADD_USER": {
      return {
        ...state,
        users: [...state.users, action.payload],
      };
    }
    default:
      return state;
  }
};

Here we add a new user to the users array in the form of action.payload which should contain all the keys you want on your user.

You can now have an action creator that's a bit more concise

const addUser = user => ({
  type: 'ADD_USER',
  payload: user,
})

And your form could be simplified a lot:

import * as actions from './actions'

class Form extends React.Component {
  state = {
    firstname: '',
    lastname: '',
  }

  render() {
    return (
      <form onSubmit={() => {
        this.props.dispatch(actions.addUser(this.state))
      }}>
        <input 
          value={this.state.firstname} 
          onChange={e => this.setState({ firstname: e.target.value })
        />
        <input 
          value={this.state.lastname} 
          onChange={e => this.setState({ lastname: e.target.value })
        />
      </form>
    )
  }
}

export default connect()(Form)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM