javascript - Filter items by category - React - Stack Overflow

I have a list of posts that are organized by category. Currently it lists them on the page like:Leisur

I have a list of posts that are organized by category. Currently it lists them on the page like:

Leisure
    -leisure post 1
    -leisure post 2
    -leisure post 3
Sports
    -sports post 1
    -sports post 2
    -sports post 3
...and so on (these are not the exact categories and posts, just and example of how they are listed on the page right now)

which is created with the following ponent:

const Posts = ({ state }) => {
  const postsPerCategory = getPostsGroupedByCategory(state.source);

  return (
    <>
      {postsPerCategory.map(({ category }, index) => {
        return (
          <button key={index}>{category.name}</button>
        )
      })}

      {postsPerCategory.map(({ posts, category }, index) => {
        return (
          <div key={index}>
            <h4>{category.name}</h4>
            {posts.map((post, index) => {
              return (
                <article key={index}>
                  {post.title.rendered}
                </article>
              )
            })}
          </div>
        )
      })}
    </>
  )
}

The console.log(postsPerCategory) returns an array with objects in the following image:

I've created a div that maps the postsPerCategory so that there is a button for each category. But I am trying to use hooks so that when each category button is selected only the posts from that category are listed. I am new to using hooks, so I am really lost on how to create the onClick function that would do what I am needing. So far for the buttons I have the following, which is already in the code above:

{postsPerCategory.map(({ category }, index) => {
  return (
    <button key={index}>{category.name}</button>
  )
})}

How would I create the function that does what i am looking for?

I have a list of posts that are organized by category. Currently it lists them on the page like:

Leisure
    -leisure post 1
    -leisure post 2
    -leisure post 3
Sports
    -sports post 1
    -sports post 2
    -sports post 3
...and so on (these are not the exact categories and posts, just and example of how they are listed on the page right now)

which is created with the following ponent:

const Posts = ({ state }) => {
  const postsPerCategory = getPostsGroupedByCategory(state.source);

  return (
    <>
      {postsPerCategory.map(({ category }, index) => {
        return (
          <button key={index}>{category.name}</button>
        )
      })}

      {postsPerCategory.map(({ posts, category }, index) => {
        return (
          <div key={index}>
            <h4>{category.name}</h4>
            {posts.map((post, index) => {
              return (
                <article key={index}>
                  {post.title.rendered}
                </article>
              )
            })}
          </div>
        )
      })}
    </>
  )
}

The console.log(postsPerCategory) returns an array with objects in the following image:

I've created a div that maps the postsPerCategory so that there is a button for each category. But I am trying to use hooks so that when each category button is selected only the posts from that category are listed. I am new to using hooks, so I am really lost on how to create the onClick function that would do what I am needing. So far for the buttons I have the following, which is already in the code above:

{postsPerCategory.map(({ category }, index) => {
  return (
    <button key={index}>{category.name}</button>
  )
})}

How would I create the function that does what i am looking for?

Share Improve this question asked Sep 12, 2020 at 1:03 kb_kb_ 1874 silver badges25 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 2

Using hooks in this case would be just for the category.name itself, so you can setup a hook like this:

const [categoryName, setCategoryName] = useState(yourDefaultCategory);

Then inside your button all you have to do is add an onclick event that calls setCategoryName(category.name) like so:

<button key={index} onClick={() => setCategoryName(category.name)}>
  {category.name}
</button>

For this to have any effect on the list you need to filter your map list by category like so:

{postsPerCategory.map(({ posts, category }, index) => {
        return categoryName === category.name? (
          <div key={index}>
            <h4>{category.name}</h4>
            {posts.map((post, index) => {
              return (
                <article key={index}>
                  {post.title.rendered}
                </article>
              )
            })}
          </div>
        ) : null
      })}

I haven't tested the above but it should work fine. You could also consider using filter instead of map. Will be a bit cleaner.

I would create a state for tracking whether each category is selected or not.

const [isSelected, setIsSelected] = useState({});

You should initialize this state when the app first rendered. This can be done with useEffect.

useEffect(() => {
  const isSelected = {};

  const categoryNames = postPerCategory.map({category} => category.name);
  categoryNames.forEach(categoryName => isSelected[categoryName] = false)

  setIsSelected(isSelected);
}, [])

Then when the button is clicked, the checked state should be toggled, as follows.

<button key={index} onClick={() => setIsSelected({...isSelected,
    [category.name] : !isSelected[category.name]})}>
  {category.name}
</button>

Finally, render the category if it is checked.

{
  postsPerCategory.filter({category} => isSelected[category.name])
    .map({category} => {
      // render here
    })
}

Based on the first answer, you can set the default category name as 'all', then check the value of categoryName==='all', if it's true, map all the postsPerCategory, otherwise check categoryName === category.name in the map function. This may not be the most efficient solution, but it works!

{
   categoryName==='all'? postsPerCategory.map(({ posts, category }, index) => 
     (
      <div key={index}>
        <h4>{category.name}</h4>
        {posts.map((post, index) => {
          return (
            <article key={index}>
              {post.title.rendered}
            </article>
          )
        })}
      </div>
     ) : postsPerCategory.map(({ posts, category }, index) => {
    return categoryName === category.name? (
      <div key={index}>
        <h4>{category.name}</h4>
        {posts.map((post, index) => {
          return (
            <article key={index}>
              {post.title.rendered}
            </article>
          )
        })}
      </div>
    ) : null
  })
 
}

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744782386a4593417.html

相关推荐

  • javascript - Filter items by category - React - Stack Overflow

    I have a list of posts that are organized by category. Currently it lists them on the page like:Leisur

    12小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信