Вот ответ на основе предоставленных вами предметов. Я извлек подпункты рисования в отдельную функцию, которая принимает аргумент элемента. Каждый подпункт имеет обработчик onClick
, который устанавливает visited
в true
.
import React, { useState, useCallback } from "react";
import ReactDOM from "react-dom";
const initialItems = [
{
id: "1",
task: "task 1",
activities: [
{
Google: [{ url: "https://www.google.com" }, { visited: false }],
Yahoo: [{ url: "https://www.yahoo.com" }, { visited: false }],
Bing: [{ url: "https://www.bing.com" }, { visited: false }]
}
]
},
{
id: "2",
task: "task 2",
activities: [
{
Facebook: [{ url: "https://www.facebook.com" }, { visited: false }],
Instagram: [{ url: "https://www.instagram.com" }, { visited: false }],
Twitter: [{ url: "https://www.twitter.com" }, { visited: false }]
}
]
}
];
function App() {
const [items, setItems] = useState(initialItems);
const setVisited = React.useCallback(
(id, activityName) => {
const item = items.find(item => item.id === id);
if (item) {
item.activities[0][activityName][1].visited = true;
setItems([...items]);
}
},
[items, setItems]
);
const getSubItems = useCallback(
item => {
const activities = item.activities[0];
return Object.keys(activities).map(activityName => {
const url = activities[activityName][0].url;
const onClick = () => {
setVisited(item.id, activityName);
};
return (
<li key={activityName}>
<a
href={url}
onClick={onClick}
target="_blank"
rel="noopener noreferrer"
>
{activityName}
</a>
</li>
);
});
},
[setVisited]
);
return (
<div>
<ul>
{items.map(item => (
<li key={item.id}>
{item.task}
<ul>{getSubItems(item)}</ul>
</li>
))}
</ul>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
ПРИМЕР