0

I'm trying to render the sorted array of objects using useMemo. Currently the last sorted array is rendering on the screen. But i want to use the select drop down where users can select different sort like title shown in code using useMemo. The users can sort by selecting title, author image.

I have used redux for sorting the array of objects.Could someone please help me with the best practice. Thanks.

I have added Post.js below the HomePage.js. Is my approach to it is wrong? Should i change the approach?

Any suggestions will be helpful.Could someone suggest me the best practies for it. Any suggestions on what am i doing wrong here?

HomePage.js

import React, { useState, useEffect, useMemo } from "react";
        import Post from "../../Components/Post/Post";
        import "./HomePage.css";
        import axios from "axios";
        
        const HomePage = () => {
          const [posts, setPosts] = useState("");
        
          let config = { Authorization: "................" };
          const url = ".........................";
        
          useEffect(() => {
            AllPosts();
          }, []);
        
          const AllPosts = () => {
            axios
              .get(`${url}`, { headers: config })
        
              .then((response) => {
                const allPosts = response.data.articles;
                console.log(response);
              })
              .catch((error) => console.error(`Error: ${error}`));
          };
        
          const newPostsByTitle = useMemo(() => {
            allPosts.sort((a, b) => a.title.localeCompare(b.title)), [posts];
          });
        
          return (
            <div className="home">
              <div className="select">
                <select
                  name="slct"
                  id="slct"
                  onChange={(e) => newPostsByTitle(e.target.value)}
                ></select>
              </div>
              <Post className="Posts" posts={posts} key={posts.title} />
            </div>
          );
        };
        
        export default HomePage;
    
    Post.js
    import React from "react";
    import "./Post.css";
    import { Fragment } from "react";
    
    const Post = (props) => {
      const displayPosts = (props) => {
        const { posts } = props;
    
        if (posts.length > 0) {
          return posts.map((post) => {
            return (
              <Fragment>
                <div className="Post" key={post.title}>
                  <img
                    src={post.urlToImage}
                    alt="covid"
                    width="100%"
                    className="img"
                  />
                  <h5 className="title"> {post.title}</h5>
                  <p className="author"> {post.author}</p>
                  <p className="description"> {post.description}</p>
                </div>
              </Fragment>
            );
          });
        }
      };
      return <div className="Posts">{displayPosts(props)}</div>;
    };
    
    export default Post;
3
  • Your useMemo function doesn’t return anything. Commented May 2, 2021 at 2:45
  • @rayhatfield currently the last sorted array is rendering on the screen. But i want to use the select drop down where users can select different sort like title shown in code using useMemo. The users can sort by selecting title, author image. Commented May 2, 2021 at 2:51
  • 1
    Your useMemo call doesn't return anything and then you're trying to use newPostsByTitle (which is undefined) as a change handler. If you want newPostsByTitle to be a function you need to return that function from your useMemo function. (This is what useCallback is for, btw.) Commented May 2, 2021 at 2:59

1 Answer 1

1

There are few issues with the useMemo function.

  • There is no allPosts variable that will be available for that function
  • There is no return inside useMemo
  • The dependency array syntax is wrong.

It should be something like the following.

const newPostsByTitle = useMemo(() => {
    return [...posts].sort((a, b) => a.title.localeCompare(b.title));
}, [posts]);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @RaviTheja how can i render it. I'm using the select dropdown for the users to sort by title, author and description. The select dropdown is HomePage.js and i'm rendering the page using Post.js Could you please advice on the same. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.