pseudostack
pseudostack

Reputation: 21

Using arr.push() to add an object to an array replacing existing value instead of adding new one

Currently trying to render a list of components that expands/shrinks as values are added/removed from an array of a custom object type. However, whenever I make the called to push a value into a new array and then pass that into a hook, the array simply replaces the previous value rather than making the list of objects longer. Any help appreciated.

// My interface
interface IAddedSkill {
    id: string,
    level: Level,
    name: string,
}

const [potentialSkills, setPotentialSkills] = useState<IAddedSkill[]>([]);
let addedSkills: IAddedSkill[] = [];

function handleAddedSkills(addedSkill: IAddedSkill) {
        addedSkills.push(addedSkill);
        setPotentialSkills(addedSkills);
    }
    ...some code in between
    // Rendering the react component using this hook
    {potentialSkills.map(skill => (
          <Chip label={skill.name} onDelete={() => handleDelete(skill)} />
          ))}

Can anyone see something I'm doing wrong that would cause this behaviour?

Edit: Thanks for all the answers, the implementation I used that resolved the issue was changing the handleAddSkills function to:

function handleAddedSkills(addedSkill: IAddedSkill) {
    setPotentialSkills([...potentialSkills, addedSkill]);
}

I also completely removed any reference to the addedSkills list and removed the declaration.

Upvotes: 0

Views: 999

Answers (3)

javoski
javoski

Reputation: 61

Your code is redeclaring the variable addedSkills every render with an empty array, so you are setPotentialSkills with addedSkills which's length always equals 1.

You can just remove addedSkills, and invoke setPotentialSkills like:

setPotentialSkills((previousSkills) => [...previousSkills, addedSkill]);

Upvotes: 2

lpizzinidev
lpizzinidev

Reputation: 13289

Remove the addedSkills array and update the potentialSkills state directly:

const [potentialSkills, setPotentialSkills] = useState<IAddedSkill[]>([]);

function handleAddedSkills(addedSkill: IAddedSkill) {
    setPotentialSkills((oldSkills) => [...oldSkills, addedSkills]);
}

Upvotes: 1

Tobias S.
Tobias S.

Reputation: 23825

You also need to make addedSkills a state variable otherwise it will get overwritten every time your component renders.

let [addedSkills, setAddedSkills] = useState([])

Upvotes: 1

Related Questions