How maltiple value using usestate localstorage in react? - javascript

I want to work using maltiple values in use state and crud in local storage use state like
const [Data,setData]=[[{
name:'luis',
pass:'1234',
//.......
}]
]
And it updates with the form
<input>
// .......
if value true Display take look at this example I try but I cannot do how to solve it
import './App.css';
import React, { useState,useEffect } from 'react';
function App() {
const [User, setUser] = useState([
{
Name:'',
Pass:'',
Email:'',
}
]);
const [storedUser,setstoredUser]=useState([])
const handle = () => {
localStorage.setItem(JSON.stringfy(...User))
setstoredUser(...User);
};
const remove = () => {
localStorage.removeItem();
};
return (
<div className="App">
<h1>Name of the user:</h1>
<input
placeholder="Name"
name='Name'
value={User.Name}
onChange={(e) => setUser({...User,[e.target.name]:[e.target.value]})}
/>
<h1>Password of the user:</h1>
<input
type="password"
name="Pass"
placeholder="Password"
value={User.Pass}
onChange={(e) => setUser({...User,[e.target.name]:[e.target.value]})}
/>
<h1>Email of the user:</h1>
<input
type="mail"
name="Email"
placeholder="Email"
value={User.Email}
onChange={(e) => setUser({...User,[e.target.name]:[e.target.value]})}
/>
<div>
<button onClick={handle}>Done</button>
</div>
{storedUser.Name && (
<div>
Name: <p>{localStorage.getItem('Name')}</p>
</div>
)}
{storedUser.Pass && (
<div>
Password: <p>{localStorage.getItem('Pass')}</p>
</div>
)}
{storedUser.Email && (
<div>
Password: <p>{localStorage.getItem('Email')}</p>
</div>
)}
<div>
<button onClick={remove}>Remove</button>
</div>
</div>
);
}
export default App;
Here I try how to do this formate I try to all data in state and stringify set this local storage. then remove and display I think explaine on detail

You're missing the key
localStorage.setItem("User",JSON.stringfy(...User))
If you want each key. Loop over they keys and values and set them. As stated by another user, your UserState is an array where it should just be an object
Object.entries(User).forEach(([key,value])=>{
localStorage.setItem(key,value)
})

You are doing a few things incorrectly here:
you are not providing a key for local storage
you don't need to spread objects directly inside setState
use the removeItem method to clear the user from localStorage
you are setting the user as an array to state not an object, this is unnecessary in the example you have
If the goal is to persist a single user between sessions via local storage. Then all you need to do is save the user to local storage when the form is submitted.
Then, when the component loads, check local storage for user data.
import { useEffect, useState } from 'react'
function App() {
const [User, setUser] = useState({
Name: '',
Pass: '',
Email: '',
})
const handle = () => {
const nextUser = JSON.stringify(User)
localStorage.setItem('user', nextUser)
}
const remove = () => {
localStorage.removeItem('user')
}
useEffect(() => {
const storedUser = localStorage.getItem('user')
if (storedUser) {
setUser(JSON.parse(storedUser))
}
}, [])
return (
<div className="App">
<h1>Name of the user:</h1>
<input
placeholder="Name"
name="Name"
value={User.Name}
onChange={(e) => setUser({ ...User, [e.target.name]: e.target.value })}
/>
<h1>Password of the user:</h1>
<input
type="password"
name="Pass"
placeholder="Password"
value={User.Pass}
onChange={(e) => setUser({ ...User, [e.target.name]: e.target.value })}
/>
<h1>Email of the user:</h1>
<input
type="mail"
name="Email"
placeholder="Email"
value={User.Email}
onChange={(e) => setUser({ ...User, [e.target.name]: e.target.value })}
/>
<div>
<button onClick={handle}>Done</button>
</div>
{User.Name && (
<div>
Name: <p>{User.Name}</p>
</div>
)}
{User.Pass && (
<div>
Password: <p>{User.Pass}</p>
</div>
)}
{User.Email && (
<div>
Password: <p>{User.Email}</p>
</div>
)}
<div>
<button onClick={remove}>Remove</button>
</div>
</div>
)
}
export default App

Since User already is an array of user objects I wouldn't spread them in your handle function. You also need to set a key if you're saving in localStorage. This is how to save your list of users under "users":
const handle = () => {
localStorage.setItem("users", JSON.stringfy(User));
setstoredUser(User);
};
Now when retrieving users from the localStorage you can make use of JSON.parse like this:
users = JSON.parse(localStorage.getItem("users") || "[]");
And for deletion you would need the key "users" here as well:
localStorage.removeItem("users");

Related

Redux-from with useState - how to connect with value from redux?

Is it possible to substitute the value from useState with the one coming from input?
Or is there a way to do this using dispatch?
I have tried many ways, but none of them work.
const renderInput = ({
input,
label,
type,
meta: { asyncValidating, touched, error },
}) => {
const [value, setValue] = useState('default state');
const onChange = event => {
setValue(event.target.value);
// + some logic here
};
return (
<div>
<label>{label}</label>
<div className={asyncValidating ? 'async-validating' : ''}>
<input {...input} value={value} onChange={onChange} type={type} placeholder={label} />
{touched && error && <span>{error}</span>}
</div>
</div>
);
};
const SelectingFormValuesForm = props => {
const { type, handleSubmit, pristine, reset, submitting } = props;
return (
<form onSubmit={handleSubmit}>
<div>
<label>Name</label>
<div>
<Field
name="name"
component={renderInput}
type="text"
placeholder="Dish name..."
/>
</div>
</div>
</form>
);
};
SelectingFormValuesForm = reduxForm({
form: 'selectingFormValues',
validate,
asyncValidate,
// asyncBlurFields: ['name'],
})(SelectingFormValuesForm);
export default SelectingFormValuesForm;
This way, unfortunately, the value sent to the submit remains empty.

Why event target not passing through multiple react functions?

So I am trying to make a textfield component in React that is highly reusable but whenever I try to access event.target.name or event.target.value I get empty data.
Is there any way to get this code to work?
function LoginForm() {
const [form, setValues] = useState({
username: "",
password: ""
});
const printValues = e => {
e.preventDefault();
console.log(form.username, form.password);
};
const updateField = e => {
setValues({
...form,
[e.target.name]: e.target.value
});
};
const TextField = props => {
return(
<label>
React Component:
<input
value={props.value}
name='react'
onChange={e => props.change(e)}
/>
</label>
)
}
return (
<form onSubmit={printValues}>
<TextField
value={form.username}
name='username'
change={updateField}
/>
<br />
<TextField
value={form.password}
name='password'
change={updateField}
/>
<br />
<button>Submit</button>
</form>
);
}
This code is an example that I have gotten to work. Why does this code work but not the code above?
function LoginForm() {
const [form, setValues] = useState({
username: "",
password: ""
});
const printValues = e => {
e.preventDefault();
console.log(form.username, form.password);
};
const updateField = e => {
setValues({
...form,
[e.target.name]: e.target.value
});
};
return (
<form onSubmit={printValues}>
<label>
Username:
<input
value={form.username}
name="username"
onChange={updateField}
/>
</label>
<br />
<label>
Password:
<input
value={form.password}
name="password"
type="password"
onChange={updateField}
/>
</label>
<br />
<button>Submit</button>
</form>
);
}
your child component has it's name prop hardcoded name='react' and that's because your [e.target.name]: e.targe.value statement is not working, use name={props.name} instead and it would solve the problem.
const TextField = props => {
return(
<label>
React Component:
<input
value={props.value}
name={props.name}
onChange={e => props.change(e)}
/>
</label>
)
}
The first code you show has a prop change instead of the onChange event listener in the TextField component.
I was looking here https://material-ui.com/es/components/text-fields/ because I never used material-ui, and in the example they still use the regular onChange.
So try changing change for onChange, as it is the only difference between both code examples besides the use of the component.

React onChange not updating state

I am creating a simple login form and I am saving the users information to state as they type. However, the value does not register to state as expected.
Here is the user state
const [user, setUser] = useState({
firstName: '',
lastName: '',
email: ''
});
Here is the input component
export function Input({ id, placeholder, autoComplete, type, name, label, value, handleInputChange }) {
return (
<div className="form-input">
<label className="form-label" htmlFor={id}>{label}</label>
<input
placeholder={placeholder}
autoComplete={autoComplete}
id={id}
type={type}
name={name}
value={value}
onChange={handleInputChange}
/>
</div>
)
}
Here is the handleInputChange function that is passed into the input component
function handleInputChange(event) {
const { name, value } = event.target;
setUser({ ...user, [name]: value });
}
Here is how one of the input components is used in the parent component
<Input
id="first-name"
placeholder="Charlie"
autoComplete="given-name"
type="text"
name="firstName"
label="First Name"
value={user.firstName}
handleInputChange={handleInputChange}
/>
Here are some resources I've looked at thus far:
https://reactjs.org/docs/hooks-reference.html#usestate
onChange not updating React
https://daveceddia.com/usestate-hook-examples/
I'd suggest to create one state per input field:
export function Form({ addItem }) {
const [name, setName] = useState('');
return (
<form>
<Input
id="first-name"
placeholder="Charlie"
autoComplete="given-name"
type="text"
name="firstName"
label="First Name"
value={user.firstName}
handleInputChange={(event) => setName(event.target.value)}
/>
</form>
);
}

HandleChange/setState stopped working after migrating to react useState hook

I had a component using classBased react, and it was working fine, I decided to switch to usestate and it stopepd working. Now the handlechange records the state in a random manner, but it doesnt work properly
My handlechange and the useState
const [state, setState] = useState({
email: "",
password: "",
wrongCombo: false,
serverError: false
})
const handleChange = (evt) => {
const target = evt.target;
const value = target.value;
const name = target.name;
console.log(name)
console.log(value)
setState({
[name]: value
});
}
My handlesubmit (it detects random values in that console.log, icant find the logic, but the log wont get both values as per inputed in the handlechange)
const handleSubmit = (event) => {
event.preventDefault();
const { email, password } = state;
console.log(state)
props.login(email, password, "login").
then(data => {
}).catch((err) => {
if (err == "Error: Request failed with status code 403") {
setState({
wrongCombo: true
}, () => {
})
} else if (err == "Network error") {
setState({
serverError: true
})
}
})
}
And this is my render
<div>
<form>
{state.wrongCombo ? <Alert variant="danger" dismissible onClose={handleDismiss}> Wrong email and password combination </Alert> : null}
{state.serverError ? <Alert variant="danger" dismissible onClose={handleDismiss}> Server Error </Alert> : null}
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" name="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" onChange={handleChange} />
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" name="password" class="form-control" id="exampleInputPassword1" placeholder="Password" onChange={handleChange} />
</div>
<div className="text-center buttonContainer">
<button type="submit" class="btn btn-primary buttonLogin" onClick={handleSubmit}>Submit</button>
</div>
</form>
</div>
From the docs on useState:
unlike this.setState in a class, updating a state variable always replaces it instead of merging it.
You must replace all values in a useState object when updating them. You are only providing an object to the updater with one of the keys, so only that key will be retained.
A simple pattern for doing this would be to spread the previous state before passing your update:
setState(prev => ({...prev, [newKey]: newVal }));

Store Values from Material UI's form in TypeScript

What's the best way to store values typed into the text fields here?
const AddUserPage = () => (
<div>
<PermanentDrawerLeft></PermanentDrawerLeft>
<div className='main-content'>
<form className="ROOT" noValidate autoComplete="off">
<TextField id="standard-basic" label="Standard" />
</form>
</div>
</div>
);
export default AddUserPage;
I want to find a way such that I can use the stored values in my GraphQL mutations as well, without having to modify the const() structure of my page. I don't want to use the Class Component Extend or function structure here.
What is your const() structuremakes:
=> (This is the auto return syntax.)
If you want to store/reuse your value, you will have to define some state/variable to store the data.
You can also do it in upper component like:
import React, { useState } from "react";
const Parent = props => {
const [state, setState] = useState({ text: "" });
return <AddUserPage value={state.text} onChange={e => setState(prev => ({ ...prev, text: e.target.value || "" }))} />
}
const AddUserPage = ({ value = "" , onChange }) => (
<div>
<PermanentDrawerLeft></PermanentDrawerLeft>
<div className='main-content'>
<form className="ROOT" noValidate autoComplete="off">
<TextField id="standard-basic" value={value} onChange={onChange} label="Standard" />
// value, and Onchange comes from an upper component
</form>
</div>
</div>
);

Categories