Reputation: 566
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
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
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