skip to Main Content

I am creating an items listing with categories.

I want to have it such that when user first visits the site, the default first category should be active, but at the moment, all items are appearing.

After clicking on particular category then item results are right.

You can check full codesandbox here.

2

Answers


  1. Consider setting the initial state of workitems items to the first category:

    const allCategoriesList = [
      ...new Set(workingList.map((work) => work.category)),
    ];
    
    function App() {
      // …
      const [workItems, setWorkItems] = useState(
        workingList.filter((item) => item.category === allCategoriesList[0])
      );
    
    const { useState } = React;
    const { motion, AnimatePresence } = Motion;
    
    function WorkItems({ workItems }) {
      return (
        <React.Fragment>
          {workItems.map((workItem) => {
            const { id, img, title, subtitle } = workItem;
            return (
              <motion.div
                layout
                animate={{ opacity: 1, scale: 1 }}
                initial={{ opacity: 0.8, scale: 0.6 }}
                exit={{ opacity: 0.8, scale: 0.6 }}
                transition={{ duration: 0.5 }}
                className="work-items"
                key={id}
              >
                <div className="">
                  {/* <div className=''>
                            <img src={img} alt='' className='' />
                        </div> */}
                  <p>{title}</p>
                </div>
              </motion.div>
            );
          })}
        </React.Fragment>
      );
    }
    
    function WorkList({ workList, filterItems }) {
      const [active, setActive] = useState(0);
    
      return (
        <div className="work-list">
          {workList.map((category, index) => {
            return (
              <div
                className={`${
                  active === index ? "active-list" : ""
                } work-list-category`}
                key={index}
                onClick={() => {
                  setActive(index);
                  filterItems(category);
                }}
              >
                {category}
              </div>
            );
          })}
        </div>
      );
    }
    
    const workingList = [
      {
        id: 1,
        category: "Website",
        title: "MH Connectors",
        subtitle:
          "MH Connectors is a leader in the design, worldwide manufacture and marketing of I/O interconnect products serving the Electronics, Data-communication, Tele-communication and Industrial Controls market places. With over forty six years experience in the electronics industry, coupled with our ability to design and manufacture high quality interconnect solutions we are well positioned to assist with all your interconnection requirements.",
      },
      {
        id: 2,
        category: "Website",
        title: "NU GEN Eugby",
        subtitle: "NU GEN Eugby Website Development",
      },
      {
        id: 3,
        category: "Games",
        title: "Dot Boxes",
        subtitle: "",
      },
      {
        id: 4,
        category: "Games",
        title: "Football Quiz",
        subtitle: "",
      },
      {
        id: 5,
        category: "Application",
        title: "Battery Magic",
        subtitle:
          "Battery Magic is a super simple & beautiful app to check your battery status & system status. - Accurate battery percentage view - Real time battery usage stats metrics - Remaining time for different tasks on the battery level - Animated and cool graphs to enhance the user experience - The perfect support iOS7 and IPhone5s/5c 4.0 inches screen display - It's FREE and will always be.",
      },
      {
        id: 6,
        category: "Application",
        title: "Beer Pedia",
        subtitle:
          "Beerpedia is the IMDB of Breweries! A Beer Wikipedia in Your Pocket! Beerpedia is the largest database of thousands of beers form around the world. A better way to discover craft beer. With the largest database of breweries, beers, beer events and guilds, our service is just about the facts. All of our data is curated by our administrators, so you can be sure that the information you get is timely and accurate.",
      },
    ];
    
    const allCategoriesList = [
      ...new Set(workingList.map((work) => work.category)),
    ];
    
    function App() {
      const [categories, setCategories] = useState(allCategoriesList);
      const [workItems, setWorkItems] = useState(
        workingList.filter((item) => item.category === allCategoriesList[0])
      );
    
      const filterItems = (category) => {
        const newWorkItems = workingList.filter(
          (item) => item.category === category
        );
        setWorkItems(newWorkItems);
      };
    
      return (
        <div className="App">
          <h1>Hello CodeSandbox</h1>
          <h2>Start editing to see some magic happen!</h2>
          <WorkList workList={categories} filterItems={filterItems} />
    
          <AnimatePresence initial={false}>
            <WorkItems workItems={workItems} />
          </AnimatePresence>
        </div>
      );
    }
    
    ReactDOM.createRoot(document.getElementById("app")).render(<App />);
    .App {
      font-family: sans-serif;
      text-align: center;
      align-items: center;
      justify-content: center;
    }
    
    .work-list {
      display: flex;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script src="https://unpkg.com/[email protected]/dist/framer-motion.js"></script>
    
    <div id="app"></div>
    Login or Signup to reply.
  2. It’s because for the workItems state, you initialize it with useState(workingList) which contains all the items. Meanwhile, the filtering based on the category happens only after a WorkList element is clicked (which call the setWorkItems).

    My advice is to put the active state in the root directly App.js, and remove the workingItems state. Instead, you can make it directly as a variable that is calculated during render. Also, for things that don’t change (like categories state here), you don’t need to put it inside useState.

    Codesandbox

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search