Reputation: 85
I want to add items to an array with the useState hook instead of doing array.push. This is the original code:
let tags = []
data.blog.posts.map(post => {
post.frontmatter.tags.forEach(tag => {
if (!tags.includes(tag)){
tags.push(tag)
}
})
})
This is one of several things I've tried with React:
const [tags, setTags] = useState([])
data.blog.posts.map(post => {
post.frontmatter.tags.map(tag => {
if (!tags.includes(tag)){
setTags(tags => [...tags, tag])
}
})
})
The "tags" state variable does not receive anything in the above example.
I have looked at a variety of similar threads but the problems and solutions there are difficult to translate to this situation.
Upvotes: 1
Views: 341
Reputation: 2660
Ok, I did understand what you wanted to do.
Here is the code and I did add some commest and there is also a working code sandbox
so it will show the "tags" you have on your state and when you click on the button it will filter and add those tags that are missing
import React, { useState } from "react";
//mock data.blog.posts
const data = {
blog: {
posts: [
{
frontmatter: {
tags: ["tag1", "tag2", "tag3"]
}
}
]
}
};
const App = () => {
const [tags, setTags] = useState(["tag1"]);
const filterTags = () => {
const myTags = ["tag1"];
let result;
data.blog.posts.map((post) => {
// check what tags are not included in tag stateon line 18
result = post.frontmatter.tags.filter((item) => !tags.includes(item));
});
// here it will show that 'tag2' and 'tag3' does not exist
console.log("result", result);
// here we are setting the state
setTags((oldState) => [...oldState, ...result]);
};
return (
<div className="App">
<h1>My tags</h1>
{tags.map((tag) => (
<h4>{tag}</h4>
))}
<button onClick={() => filterTags()}>add tags</button>
<hr />
<h1>My tags from posts</h1>
{data.blog.posts.map((posts) => {
return posts.frontmatter.tags.map((tag) => <div>{tag}</div>);
})}
</div>
);
};
export default App;
and here is the codeSandBox
Upvotes: 0
Reputation: 383
You can try setting the tags state in initial render or on any event as per your requirement .
const [tags, setTags] = useState([]);
useEffect(()=>{
const arr=[];
data.blog.posts.map(post => {
post.frontmatter.tags.map(tag => {
if (!arr.includes(tag)){
arr.push(tag)
}
})
});
setTags([...arr]);
},[]);
Upvotes: 1