I started learning React not so long ago. Decided to make some kind of "life checklist" as one of my beginner projects. I have been using Functional Components in the core.
FYI:
const App = () => {
  //Looping over data
  const items = data.map((item) => {
    return (
      <ChecklistItem action={item.action} emoji={item.emoji} key={item.id} />
    );
  });
  return (
    <>
      <GlobalStyle />
      <StyledHeading>Life Checklist</StyledHeading>
      <StyledApp>{items}</StyledApp>
      <h2>Overall number: {data.length}</h2>
    </>
  );
};
export default App;
Here is my <ChecklistItem/> component:
const ChecklistItem = ({ action, emoji }) => {
  //State
  const [isActive, setIsActive] = useState(false);
  //Event Handlers
  const changeHandler = () => {
    setIsActive(!isActive);
  };
  return (
    <StyledChecklistItem isActive={isActive}>
      <input type="checkbox" checked={isActive} onChange={changeHandler} />
      <StyledEmoji role="img">{emoji}</StyledEmoji>
      <StyledCaption>{action}</StyledCaption>
    </StyledChecklistItem>
  );
};
export default ChecklistItem;
I would be satisfied with the functionality so far, but I need to show how many "active" checklist items were chosen in the parent <App/> component like "You have chosen X items out of {data.length}. How can I achieve this?
I assume that I need to lift the state up, but cannot understand how to implement this properly yet.
You can do that by simply creating a state for storing this particular count of active items.
To do that, you would need to update your <App/> component to something like this
const App = () => {
  const [activeItemsCount, setActiveItemsCount] = useState(0);
  //Looping over data
  const items = data.map((item, index) => {
    return (
      <ChecklistItem
        key={index}
        action={item.action}
        emoji={item.emoji}
        setActiveItemsCount={setActiveItemsCount}
      />
    );
  });
  return (
    <>
      <h1>Life Checklist</h1>
      <div>{items}</div>
      <div>Active {activeItemsCount} </div>
      <h2>Overall number: {data.length}</h2>
    </>
  );
};
export default App;
And then in your <ChecklistItem /> component, you would need to accept that setActiveItemsCount function so that you can change the state of the activeItemsCount.
import React, { useState, useEffect } from "react";
const ChecklistItem = ({ action, emoji, setActiveItemsCount }) => {
  const [isActive, setIsActive] = useState(false);
  const changeHandler = () => {
    setIsActive(!isActive);
  };
  useEffect(() => {
    if (!isActive) {
      setActiveItemsCount((prevCount) => {
        if (prevCount !== 0) {
          return prevCount - 1;
        }
        return prevCount;
      });
    }
    if (isActive) {
      setActiveItemsCount((prevCount) => prevCount + 1);
    }
  }, [isActive, setActiveItemsCount]);
  return <input type="checkbox" checked={isActive} onChange={changeHandler} />;
};
export default ChecklistItem;
By using the useEffect and the checks for isActive and 0 value, you can nicely increment or decrement the active count number by pressing the checkboxes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With