AlyaKra
AlyaKra

Reputation: 566

React: Show and hide specific element in list

The following list is displaying input as data for a list.

I added a toggle near every element in the list so I can hide it specifically.

For now when I'm clicking on the toggle, the whole list hides and shows, while I want only the selected element to be hidden/shown.

I tried setting setShowurl(!showurl); in handleChangeUpdate but it didn't work.

How to do so ?

const F = () => {
  const initialList = [
    {
      id: "a",
      title: "Random title 1",
      description: "Random description 1"
    },
    {
      id: "b",
      title: "Random title 2",
      description: "Random description 2"
    },
    {
      id: "c",
      title: "Random title 3",
      description: "Random description 3"
    }
  ];

    const [list, setList] = React.useState(initialList);

// This is the area to update a specific element in the list

    function handleChangeUpdate(id, event) {
    const { name, value } = event.target;
    const newList = list.map((item) => {
      if (item.id === id) {
        const updatedItem = {
          ...item,
          [name]: value
        };

        return updatedItem;
      }
      return item;
    });

    setList(newList);

// This is the area for toggle

  const [showurl, setShowurl] = useState(true);

  const hideComponent = (name) => {
    console.log(name);
    switch (name) {
       case "showurl":
        setShowurl(!showurl);
        break;
      default:
    }
  };
  }

  return (
    <div>
      <ul>
        <div>{showurl && 
          {list.map((item) => (
            <li key={item.id}>
              <label>        
              <input type="checkbox" name="select" onClick={() =>
              {hideComponent("showurl")}}  
               />
               <span />
                </label>
              <input
                name="title"
                className="form-control"
                onChange={(e) => handleChangeUpdate(item.id, e)}
                defaultValue={item.title}
              ></input>
              <input
                name="description"
                className="form-control"
                onChange={(e) => handleChangeUpdate(item.id, e)}
                defaultValue={item.description}
              ></input>
            </li>
          ))}
        }</div>
      </ul>
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(
  <F />,
  rootElement
);

Upvotes: 0

Views: 157

Answers (2)

amir
amir

Reputation: 218

First thing first there are a lot of type errors in the code you gave,
next time make sure the code can run and will not crush the best thing is to give sandbox link

now:
when you click on the checkbox you calling that function:

  const hideComponent = (name) => {
        console.log(name);
    switch (name) {
      case "showurl":
        setShowurl(!showurl);
        break;
      default:
    }
  };

if you will check you will see that you are changing the state showurl
this state render the whole html part:

  return (
        <div>
            <ul>
                <div>{showurl &&
                    list.map((item) => ( ...

when you calling that function you actually set this value to false and then you dont render anything

so what you need to do is:

import React, { useState } from "react";

const initialList = [
  {
    id: "a",
    title: "Random title 1",
    description: "Random description 1"
  },
  {
    id: "b",
    title: "Random title 2",
    description: "Random description 2"
  },
  {
    id: "c",
    title: "Random title 3",
    description: "Random description 3"
  }
];

export default function Test() {
  const [list, setList] = React.useState(initialList);
  const [showurl, setShowurl] = useState(true);


  function handleChangeUpdate(id, event) {
    const { name, value } = event.target;
    const newList = list.map((item) => {
      if (item.id === id) {
        const updatedItem = {
          ...item,
          [name]: value
        };

        return updatedItem;
      }
      return item;
    });

    setList(newList);
  }

  const hideComponent = (name, id) => {
        console.log(name);
    switch (name) {
      case "showurl":
                const newList = list.filter(item => item.id !== id)
        setList(newList);
        break;
      default:
    }
  };

  return (
        <div>
            <ul>
                <div>{showurl &&
                    list.map((item) => (
                        <li key={item.id}>
                            <label>
                                <input type="checkbox" name="select" onClick={() => { hideComponent("showurl",item.id) }}
                                />
                                <span />
                            </label>
                            <input
                                name="title"
                                className="form-control"
                                onChange={(e) => handleChangeUpdate(item.id, e)}
                                defaultValue={item.title}
                            ></input>
                            <input
                                name="description"
                                className="form-control"
                                onChange={(e) => handleChangeUpdate(item.id, e)}
                                defaultValue={item.description}
                            ></input>
                        </li>
                    ))
                }</div>
            </ul>
        </div>
  );
}

What i did: in hideComponent function i added another parameter the get the row id and then I built new list without the row with id X

Edit:
i also changed the input element at the render function. look at it

Upvotes: 1

Vulwsztyn
Vulwsztyn

Reputation: 2261

I would change

const [showurl, setShowurl] = useState(true);

to

const [showurl, setShowurl] = useState({ a: true, b: true, c: true });

and hide each element based of showurl[id]

Upvotes: 0

Related Questions