How to filter data in both directions?
I have data that I receive from the server and store in the state, I need to filter it to open and close, but since I update the state I can only close it, but how can I then open it using only the state?
const data = [
{
id: 1,
title: "Project 01",
project_id: null,
is_project: true,
},
{
id: 2,
title: "Task 01",
project_id: 1,
is_project: false,
},
{
id: 3,
title: "Task 02",
project_id: 1,
is_project: false,
},
{
id: 4,
title: "Project 02",
project_id: null,
is_project: true,
},
{
id: 5,
title: "Task 03",
project_id: 4,
is_project: false,
},
];
const [state, setState] = useState([]);
useEffect(() => {
setState(data); // my fetch req
}, []);
const onVisible = (id) => {
const filtered = state?.filter((el) => el?.project_id !== id);
setState(filtered);
};
When I click on +, the tasks disappear, but if I click on + again they will not appear again, since I am using a state, how can I make them appear again?
>Solution :
You will have to save whether the values are expanded or not. Let say if you can modify the data before storing it into response then you can introduce a new key called is_expanded to indicated whether to show it as expanded.
import { useEffect, useState } from "react";
import "./styles.css";
const data = [
{
id: 1,
title: "Project 01",
project_id: null,
is_project: true,
is_expanded: true,
},
{
id: 2,
title: "Task 01",
project_id: 1,
is_project: false,
is_expanded: true,
},
{
id: 3,
title: "Task 02",
project_id: 1,
is_project: false,
is_expanded: true,
},
{
id: 4,
title: "Project 02",
project_id: null,
is_project: true,
is_expanded: true,
},
{
id: 5,
title: "Task 03",
project_id: 4,
is_project: false,
is_expanded: true,
},
];
export default function App() {
const [state, setState] = useState([]);
useEffect(() => {
setState(data); // my fetch req
}, []);
const onVisible = (id) => {
// const filtered = state?.filter((el) => el?.project_id !== id);
setState((prevValue) => {
const newValue = [];
prevValue.forEach((value) => {
if (value.id === id || value.project_id === id) {
newValue.push({
...value,
is_expanded: !value.is_expanded,
});
} else {
newValue.push(value);
}
});
return newValue;
});
};
return (
<div className="App">
{state?.map((el) => (
<div key={el.id} style={{ display: "flex", columnGap: 8 }}>
{el?.is_project && (
<div onClick={() => onVisible(el?.id)}>+ {el.title}</div>
)}
{!el?.is_project && el?.is_expanded && (
<div style={{ marginLeft: el?.is_project ? 0 : 24 }}>
{el.title}
</div>
)}
</div>
))}
</div>
);
}
Initially, all of them are expanded. Once you toggle any project, any value that is part of it or the project will be toggled.
