I made such a project through context. But I can't save the values of checkbox and select options in memory. All other inputs work correctly. CRUD operations are fine, but when I select and confirm the gender, then when I try to edit the details of that contact, the gender of the contact is not visible. Also, the ``I want to receive information'' button at the bottom does not appear checked.
import React, { useState } from "react";
import { useContext } from "react";
import { GlobalContext } from "../../context/GlobalState";
import { useNavigate } from "react-router-dom";
import { NavLink } from "react-router-dom";
import { v4 as uuidv4 } from 'uuid';
const Form = () => {
const { ADD_CONTACT } = useContext(GlobalContext);
const [contact, setContact] = useState({
id: uuidv4(),
name: "",
surname: "",
fatherName: "",
specialty: "",
email: "",
gender: "",
updatesNotification:''
});
const { name, surname, fatherName, specialty, email } = contact;
let history = useNavigate();
const onSubmit = (e) => {
e.preventDefault();
if (contact) {
ADD_CONTACT(contact);
history("/contacts");
console.log(contact);
}
};
return (
<form onSubmit={onSubmit}>
<div >
<label >Name</label>
<div >
<input
name="name"
required
value={name}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</div>
</div>
<div >
<label >Surname</label>
<div >
<input
name="surname"
required
value={surname}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</div>
</div>
<div >
<label >Father Name</label>
<div >
<input
name="fatherName"
required
value={fatherName}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</div>
</div>
<div >
<label >Email</label>
<div >
<input
name="email"
required
value={email}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</div>
</div>
<div >
<label >Specialty</label>
<div >
<input
name="specialty"
required
value={specialty}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
</div>
</div>
<div className="mb-3 row">
<label >Job</label>
<div className="col-sm-10 d-flex justify-content-center align-items-center">
<select aria-label="Default select example">
<option selected>Bakalavr</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
</div>
<div className="mb-3 row">
<label >Gender</label>
<div className="col-sm-10">
<div >
<input
type="radio"
name="gender"
value="male"
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
<label >Kisi</label>
</div>
<div >
<input
type="radio"
name="gender"
value="female"
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.value })
}
/>
<label >Female</label>
</div>
</div>
</div>
<div >
<input type="checkbox" />
<label for="flexCheckDefault">
I want to be notified of updates
</label>
</div>
<button type="submit" >
Create a new contact
</button>
<NavLink to="/contacts" className="btn btn-danger m-2">
Cancel
</NavLink>
</form>
);
};
export default Form;
import React from "react";
import { NavLink } from "react-router-dom";
import { useContext, useState, useEffect } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { GlobalContext } from "../../context/GlobalState";
const EditContactForm = () => {
const { contacts, UPDATE_CONTACT } = useContext(GlobalContext);
const [selectedContact, setSelectedContact] = useState({
id: "",
name: "",
surname: "",
fatherName: "",
specialty: "",
email: "",
gender: "",
});
const history = useNavigate();
const {id} = useParams();
useEffect(() => {
const userId = id;
const selectedContact = contacts.find((user) => String(user.id) === userId);
if (selectedContact) {
setSelectedContact(selectedContact);
}
}, [id, contacts]);
function onSubmit(e) {
e.preventDefault();
UPDATE_CONTACT(selectedContact);
console.log("new user edited:", selectedContact);
history("/contacts");
}
const handleOnChange = (e) => {
setSelectedContact(selectedContact => ({
...selectedContact,
[e.target.name]: e.target.value
}));
};
return (
<div>
<form onSubmit={onSubmit}>
<div >
<label >Name</label>
<div >
<input
name="name"
required
value={selectedContact?.name ?? ''}
onChange={handleOnChange}
/>
</div>
</div>
<div >
<label >Surname</label>
<div >
<input
name="surname"
required
value={selectedContact?.surname ?? ''}
onChange={handleOnChange}
/>
</div>
</div>
<div >
<label >Father Name</label>
<div >
<input
name="fatherName"
required
value={selectedContact?.fatherName ?? ''}
onChange={handleOnChange}
/>
</div>
</div>
<div >
<label >Email</label>
<div >
<input
name="email"
required
value={selectedContact?.email ?? ''}
onChange={handleOnChange}
/>
</div>
</div>
<div >
<label >Specialty</label>
<div >
<input
name="specialty"
required
value={selectedContact?.specialty ?? ''}
onChange={handleOnChange}
/>
</div>
</div>
<div className="mb-3 row">
<label >Vezife</label>
<div className="col-sm-10 d-flex justify-content-center align-items-center">
<select aria-label="Default select example">
<option selected>Bakalavr</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
</div>
</div>
<div className="mb-3 row">
<label >Gender</label>
<div className="col-sm-10">
<div >
<input
type="radio"
name="gender"
required
value="male"
onChange={handleOnChange}
/>
<label >Male</label>
</div>
<div >
<input
type="radio"
name="gender"
value="female"
onChange={handleOnChange}
/>
<label >Female</label>
</div>
</div>
</div>
<div >
<input type="checkbox" />
<label for="flexCheckDefault">
I want to be notified of updates
</label>
</div>
<button type="submit" >
Update a contact
</button>
<NavLink to="/contacts" className="btn btn-danger m-2">
Cancel
</NavLink>
</form>
</div>
);
};
export default EditContactForm;
sandbox: https://codesandbox.io/s/task1-w5zvg4?file=/src/App.js
CodePudding user response:
When working with checkbox you have to look for e.target.checked to access if it is checked or not.
You can try something like this:
<div >
<input
type="radio"
name="gender"
id="female"
checked={contact.gender === "female"}
onChange={(e) =>
setContact({ ...contact, [e.target.name]: e.target.checked ? e.target.id : "" })
}
/>
<label htmlFor="female" >Female</label>
</div>
For the select, you can achieve this like this:
const selectOptions = [
{label: "One", value: 1},
{label: "Two", value: 2},
{label: "Three", value: 3},
]
const Test = () => {
const onChange = (e) => setContact({ ...contact, [e.target.name]: e.target.value })
return <>
<label >Job</label>
<div className="col-sm-10 d-flex justify-content-center align-items-center">
<select value={contact.test} onChange={onChange} name="test" aria-label="Default select example">
{selectOptions.map(item => (
<option key={item.value} value={item.value}>{item.label}</option>
))}
</select>
</div>
</>
}