I read the controlled and uncontrolled input from React page and follow what they recommend but somehow the warning about uncontrolled into controlled still there.
My code below is actually a page component to edit the data for the project detail. I set the values of the form to the project data after retrieve from API.
import { useState } from "react";
import { useDispatch } from "react-redux";
import {
updateProject,
deleteProject,
getProjectById,
reset,
} from "../../features/project/projectSlice";
import { useSelector } from "react-redux";
import { useNavigate, useParams } from "react-router-dom";
import { useEffect } from "react";
import { Button, Container, Form, Modal, Col, Spinner, Stack, ListGroup, Dropdown, Row } from "react-bootstrap"
import Member from "./Member";
import AddMember from "./AddMember";
function EditProject() {
// Modal
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
// Data State
const { id } = useParams();
const dispatch = useDispatch();
const navigate = useNavigate();
const { isLoading, isError, projects, isSuccess, message } = useSelector(
(state) => state.project
);
const {user} = useSelector((state)=> state.auth)
const [code, setCode] = useState("");
const [title, setTitle] = useState("");
const [desc, setDesc] = useState("");
const [users, setUsers] = useState([]);
useEffect(() => {
dispatch(getProjectById(id));
if (isError) {
console.log(message);
}
return () => dispatch(reset());
}, [isError, message, dispatch]);
useEffect(() => {
if (isSuccess && projects) {
setCode(projects.code);
setTitle(projects.title);
setDesc(projects.desc);
setUsers(projects.users);
}
}, [isSuccess,projects]);
// Data Saving
const onSubmit = (e) => {
e.preventDefault();
const projectData = {
code,
title,
desc,
users: users.map((user)=> ({...user, _user: user._user._id}))
};
const projectChanges = {
projectId: id,
projectData,
};
console.log(projectData)
dispatch(updateProject(projectChanges));
navigate("/projects");
};
if (isLoading) {
return (
<Container className="mt-5" style={{ justifyContent: "center", display: "flex" }}>
<Spinner animation="border" />
</Container>
)
}
if(user._id !== projects.manager){
return <h5>You do not have permission to edit this project</h5>
}
return (
<>
<Container fluid="md" className="mt-5">
<Form onSubmit={onSubmit}>
<Stack gap={3}>
<Form.Group>
<Form.Label>Code</Form.Label>
<Form.Control type="text" placeholder="Enter project codename" value={code} onChange={(e) => setTitle(e.target.value)} />
<Form.Text className="text-muted">Codename is a short form of the project that used widely</Form.Text>
</Form.Group>
<Form.Group>
<Form.Label>Title</Form.Label>
<Form.Control type="text" rows={5} placeholder="Enter project description" value={title} onChange={(e) => setTitle(e.target.value)} />
</Form.Group>
<Form.Group>
<Form.Label>Description</Form.Label>
<Form.Control as="textarea" rows={5} placeholder="Enter project description" value={desc} onChange={(e) => setDesc(e.target.value)} />
</Form.Group>
<Form.Group>
<Row className="mb-2">
<Col className="vertical-align"><Form.Label style={{ margin: "0" }}>Team Member</Form.Label></Col>
<Col md="auto"><Button variant="primary" onClick={handleShow}>Add People</Button></Col>
</Row>
<ListGroup>
{users && users.map((user,index) => <Member key={user._user._id} user={user} setUser={setUsers} users={users} index={index} />)}
</ListGroup>
</Form.Group>
<Row className="align-items-end">
<Col className="d-flex justify-content-end gap-2">
<Button variant="danger" className="px-3">Delete</Button>
<Button type="submit" className="px-5">Submit</Button>
</Col>
</Row>
</Stack>
</Form>
</Container>
<AddMember show={show} onHide={handleClose} />
</>
);
}
export default EditProject;
I found that the code below is source of the warning, I did remove and the warning gone. I want to know what exactly my mistake that cause the warning and the solution for this.
useEffect(() => {
if (isSuccess && projects) {
setCode(projects.code);
setTitle(projects.title);
setDesc(projects.desc);
setUsers(projects.users);
}
}, [isSuccess,projects]);
Here is sample of API retrieved,
{
"_id": "abc123",
"code": "PROJ",
"title": "Project",
"desc": "Project detail.",
"users": [
{
"_user": "1",
"role": "UI/UX Designer",
"status": "Active"
},
{
"_user": "2",
"role": "Software Engineer",
"status": "Active"
}
],
}
CodePudding user response:
This is most likely happening because one of the properties of projects
is undefined
.
Try checking that each property is not undefined before setting it:
useEffect(() => {
if (isSuccess && projects) {
if (projects.code !== undefined) {
setCode(projects.code);
}
if (projects.title !== undefined) {
setTitle(projects.title);
}
if (projects.desc !== undefined) {
setDesc(projects.desc);
}
if (projects.users !== undefined) {
setUsers(projects.users);
}
}
}, [isSuccess, projects]);
Or, you could use nullish coalescing:
useEffect(() => {
if (isSuccess && projects) {
setCode(projects.code ?? '');
setTitle(projects.title ?? '');
setDesc(projects.desc ?? '');
setUsers(projects.users ?? []);
}
}, [isSuccess, projects]);