Managing object state

DEMO

Character

Face

Hair

Accessory

When updating a object, make a shallow copy with the spread operator, and add the new key-value pair. Finally, set the state with this copy.
CharacterCustomiser.jsx

const hairs = [BlHair1, BlHair2, BlHair3, BrHair1, BrHair2, BrHair3];
const faces = [HumanMale, HumanFemale, Skeleton, Minotaur, Wolf, Bird];
const accessories = [PirateHat, Bandana, Cap, Mask, Goggles, FaceMask];

const types = {
  face: faces,
  hair: hairs,
  accessory: accessories,
};

const CharacterCustomiser = () => {
  const [character, setCharacter] = React.useState({
    face: HumanMale,
  });

  const selectItem = (type, item) => {
    let newItem = item;
    // remove item if it same as what already exists on character
    if (item === character.hair || item === character.accessory) {
      const clonedChar = { ...character };
      delete clonedChar[type];
      setCharacter(clonedChar);
      return;
    }
    if (type === "hair" || type === "face" || type === "accessory")
      setCharacter({ ...character, [type]: newItem });
  };

  return (
    <CharacterCustomiser>
      <div>
        <CategoryTitle>Character</CategoryTitle>
        <PortraitWrapper>
          <Asset src={character.face} />
          <Asset src={character.hair} />
          <Asset src={character.accessory} />
        </PortraitWrapper>
      </div>
      <InventoryWrapper>
        {Object.keys(types).map((type) => (
          <div>
            <CategoryTitle>
              {type.charAt(0).toUpperCase() + type.slice(1)}
            </CategoryTitle>
            <InventoryItems>
              {types[type].map((item) => (
                <Box
                  onClick={() => selectItem(type, item)}
                  isSelected={item === character[type]}
                >
                  <img src={item} alt="" height="80" />
                </Box>
              ))}
            </InventoryItems>
          </div>
        ))}
      </InventoryWrapper>

    </CharacterCustomiser>
  );
};  

Note: Code snippets do not include styling details unless they are the focus of the exercise.

Copyright © 2022 Explore React