I am trying to make a react example project with a way to add a ‘project’, edit its contents, view, and delete it. Just to practice with setting/changing/saving data.
I’m debating if I should make this as a functional or class component, so currently I am trying with a functional component below:
https://codesandbox.io/s/quizzical-moore-5s77l0?file=/src/Projects.js:568-570
import React, { useState } from "react";
function Projects() {
const [projects, setProjects] = useState({});
function addProject() {
console.log("addProject()");
//create project
let id = Date.now().toString().substr(8);
let newProject = {
name: `Upload-${id}`,
files: {}
};
//update projects state
let oldProjects = projects;
projects[id] = newProject;
setProjects(oldProjects);
console.log("projects = ", projects);
}
return (
<div>
<h1>Projects.js (Functional Component)</h1>
<button onClick={addProject}>Add Project</button>
<div>{Object.keys(projects).length} projs</div>
</div>
);
}
export default Projects;
when I click add projects
, I can see the project get added to the state, but my display counting how many projects there are never changes? is there additional code I need to make my dom render when the state changes? or am i using the functional component wrong?
>Solution :
Interesting question you have here. Your use of functional components isn’t really flawed. It looks like you’re getting caught on a reference issue.
Your <div>
with the project count isn’t updating because React doesn’t know it needs to update it. React doesn’t know it needs to update it because the reference to your projects
object isn’t changing. If you’re confused, just search through articles on object reference equality in JavaScript.
Long story short, your issue is with this line:
let oldProjects = projects;
A quick fix would be to do this:
let oldProjects = { ...projects };
…or this to save a few lines:
setProjects(oldProjects => ({ ...oldProjects, [id]: newProject }));
There are performance reasons why these are not flawless solutions, but if this is just to get the hang of things, I don’ think it’s a problem.