Reputation: 125
I am currently making a small form for an important assignment which demands redux. I want to create a global object which dynamically updates itself after onChange. How do I update the changes in the global object on changing input so I can use it any where ?
here are my files Details.js
import React, {useState} from "react";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import TextField from "@material-ui/core/TextField";
import {useSelector , useDispatch} from 'react-redux';
import {setUser} from './Redux/actions';
const useStyles = makeStyles({
root: {
minWidth: 400,
margin: "20px",
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)",
},
title: {
fontSize: 14,
},
pos: {
marginBottom: 12,
},
text: {
width: 300,
margin: "10px",
},
});
export default function Details() {
const classes = useStyles();
const bull = <span className={classes.bullet}>•</span>;
const [user , setUsers] = useState({
username:"",
email:"",
phone:0,
age:0,
month:"",
batch:"",
isPaid:0
})
const dispatch = useDispatch();
const handleChange = (e) => {
setUsers({ ...user, [e.target.name]: e.target.value });
}
return (
<Card className={classes.root}>
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
variant="h5"
gutterBottom
>
Enter Your Details
</Typography>
<TextField
id="filled-basic"
label="Full Name"
variant="filled"
name = "name"
className={classes.text}
onChange = {handleChange}
/>
<TextField
id="filled-basic"
label="Phone number"
variant="filled"
name = "phone"
className={classes.text}
onChange = {handleChange}
/>
<TextField
id="filled-basic"
label="Email"
variant="filled"
name = "email"
className={classes.text}
onChange = {handleChange}
/>
<TextField
id="filled-basic"
label="Age"
variant="filled"
name = "age"
className={classes.text}
onChange = {handleChange}
/>
</CardContent>
</Card>
);
}
actions.js
export const SET_USER_PROFILE = 'SET_USER_PROFILE';
export const setUser = name => dispatch => {
dispatch({
type:SET_USER_PROFILE,
payload:name
})
}
reducers.js
import { SET_USER_PROFILE } from "./actions";
const initialState = {
}
function userReducer(state = initialState , action){
switch(action.type){
case SET_USER_PROFILE:
return {...state , name:action.payload};
default:
return state;
}
}
export default userReducer;
store.js
import {legacy_createStore as createStore , combineReducers , applyMiddleware} from 'redux'
import thunk from "redux-thunk"
import userReducer from './reducers'
const rootReducer = combineReducers({userReducer});
export const Store = createStore(rootReducer , applyMiddleware(thunk))
Upvotes: 2
Views: 1549
Reputation: 203466
It seems like you are asking how to convert from using local component state to redux state.
Move the username
, email
, phone
, and age
state into the userReducer
function's initialState
.
const initialState = {
username: "",
email: "",
phone: "",
age: ""
};
Update userReducer
to consume an action payload that contains the key and value for the nested state you want to update.
const userReducer = (state = initialState, action) => {
switch (action.type) {
case SET_USER_PROFILE:
const { key, value } = action.payload;
return { ...state, [key]: value };
default:
return state;
}
};
Update the setUser
action creator function to take the key
and value
you want to update and return the action payload. There's no asynchronous logic here so there's no need to write a Thunk function that is also passed the dispatch
function.
const setUser = (key, value) => ({
type: SET_USER_PROFILE,
payload: { key, value }
});
Update the Details
component to select the user
state from Redux and update the handleChange
callback to dispatch the setUser
action with the appropriate payload values. Since these are likely supposed to be controlled inputs you'll want/need to specify the value
prop on the fields and pass the appropriate state.
const dispatch = useDispatch();
const { username, email, phone, age } = useSelector((state) => state.user);
const handleChange = (e) => {
const { name, value } = e.target;
dispatch(setUser(name, value));
};
return (
<Card className={classes.root}>
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
variant="h5"
gutterBottom
>
Enter Your Details
</Typography>
<TextField
id="filled-basic"
label="Full Name"
variant="filled"
name="username"
value={username}
className={classes.text}
onChange={handleChange}
/>
<TextField
id="filled-basic"
label="Phone number"
variant="filled"
name="phone"
value={phone}
className={classes.text}
onChange={handleChange}
/>
<TextField
id="filled-basic"
label="Email"
variant="filled"
name="email"
value={email}
className={classes.text}
onChange={handleChange}
/>
<TextField
id="filled-basic"
label="Age"
variant="filled"
name="age"
value={age}
className={classes.text}
onChange={handleChange}
/>
</CardContent>
</Card>
);
Upvotes: 2