Reputation: 1953
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 i.e 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:
Upvotes: 0
Views: 132
Reputation: 20614
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)
Upvotes: 1