Reputation:
I'm learning redux and can able to update single input field but when there's more than 1 input field can't able to update state of both input field!
Here's my code please check it.
My main index.js:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import {FormReducer} from "./reducers/name";
import { createStore } from "redux";
import { Provider } from "react-redux";
const store = createStore(FormReducer);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
My presentational and input field component:
import React, { Component } from "react";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import * as actions from "./actions";
class App extends Component {
inputData = event => {
this.props.actions.addToDo({ name: event.target.value });
};
submitData = event => {
console.log(this.props.name);
// console.log(this.props.mobile);
event.preventDefault();
}
render() {
return (
<div>
<form onSubmit={this.submitData}>
FirstName:
<input
type="text"
name={this.props.name}
onChange={this.inputData}
/>
<input
type="text"
name={this.props.mobile}
onChange={this.inputData2}
/>
<button type="submit">Submit</button>
</form>
{this.props.name}
{this.props.mobile}
</div>
);
}
}
const mapStateToProps = state => ({
mobile: state.mobile,
name: state.name
});
const mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators(actions, dispatch)
};
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
In my presentational component I want to make input acceptance such like array like [event.target.name]:event.target.value or something like this. But when I try to do this with redux it's not working properly. Please check my code and give your input!
My reducer function:
let init = {
name: ''
}
export const FormReducer = (state = init, action) => {
switch (action.type) {
case "ADD_NAME":
return {...state, name:action.name, mobile:action.mobile}
default:
return state;
}
};
My action function which takes action on new input:
let init = {
name: ''
}
export const FormReducer = (state = init, action) => {
switch (action.type) {
case "ADD_NAME":
return {...state, name:action.name, mobile:action.mobile}
default:
return state;
}
};
And also as you can see I want to print both name and mobile both but it's only printing on which I'm working. Please give code so that I can able to print both simultaneously.
Thanks in advance!
Upvotes: 0
Views: 2416
Reputation: 15292
It should be like this.
Use ecma6#computed property name
[event.target.name]
inputData = event => {
this.props.actions.addToDo({ [event.target.name]: event.target.value });
};
EDIT :
in reducers,add this .
let init = {
name: { key : "name", value : "" },
mobile: { key: "mobile", value: "" },
};
reducer :
case "ADD_NAME":
console.log(action,state);
return {
...state,
name: {
...state.name, value: action.name||state.name.value
},
mobile: {
...state.mobile,
value: action.mobile || state.mobile.value
}
};
If you checked in render,both input field need name
attribute which is not initialised and coming blank via props
mapped in mapStateToProps
.
So,you are not getting name
attribute in event handler.
Need to initilise it.I assumed mobile
and name
.
Upvotes: 1
Reputation: 1064
1rst make state and save field inputs there like this.
state = {
username: "",
password: ""
}
where updateValue will save values from inputs to state
updateValue = (e) => {
this.setState({ [e.target.name]: e.target.value });
}
<input type="text" name="username" value={this.state.username} onChange={(e) => this.updateValue(e)} />
<input type="password" name="password" value={this.state.password} onChange={(e) => this.updateValue(e)} />
then you can collect data from state and pass it to your function, for example like this login form.
submitData = event => {
const user = {
username: this.state.username,
password: this.state.password
}
// now pass this `user` to your action
event.preventDefault();
}
Upvotes: 0