Can you sort an array of react components? Accessing info of react componenet

别等时光非礼了梦想. 提交于 2020-05-15 21:32:10

问题


I have an array of posts that I am trying to sort by date - I cant figure out how to get access to the date though, since the array is a list of react components, not objects. Here is how the code is working now...

The user searches for 'bands' and it creates an array of all the band objects. Each band object has a bunch of posts in band.posts. So to get all the posts out of all of the bands I map through all the bands, then for each band I map through all of their posts. Each post then goes through the function 'convertPost()' to convert it into the component. I now have an array of post components. This is what I want to sort. Here is the code that does all of that -

{bandTypes === 'all' ? allBands.map(band => {
    if(band.youtube.length > 0 && band.bandBio !== 'n/a' && band.bandGenre !== 'n/a'){
        return band.posts.map(post => {
            let currPost = convertPost(post, band)
            return currPost
        })
    }
}).forEach(post => console.log(post)) : null}

I used a .forEach() to console.log each post - It returns the console.log of the react component... The date is located in props.post.date

    0:
$$typeof: Symbol(react.element)
key: "NOLA DUDES"
props:
    addFavorites: (userId, band) => {…}
    band: {quoteGenerator: Array(0), youtube: Array(1), posts: Array(2), favorites: Array(1), _id: "5eb20ce78b8cee4494eb44a0", …}
    bandBio: "This is my new band bioThis is my new band bioThis is my new band bioThis is my new band bioThis is my new band bioThis is my new band bio"
    bandName: "NOLA DUDES"
    favorites: ["5e8b54337d9c710ca6f117fa"]
    id: "5eb20ce78b8cee4494eb44a0"
    post:
        approved: null
        data: ""
        date: "2020-05-06T01:03:35.818Z"
        postId: "55445155-0690-46d4-a3bb-4cfd2ea160c3"
        rockOn: []
        type: "band"
__proto__: Object
youtube: ["4_eLn4B9MzQ"]
key: (...)
get key: ƒ ()
__proto__: Object
ref: null
type: ƒ BandCard(props)
_owner: FiberNode {tag: 0, key: null, stateNode: null, elementType: ƒ, type: ƒ, …}
_store: {validated: false}
_self: null
_source: {fileName: "/Users/NickMcLean/Desktop/REACT/AutoQuoteGenerator…t/src/components/Profile/SearchInputs/MainFeed.js", lineNumber: 209, columnNumber: 25}
__proto__: Object
1: {$$typeof: Symbol(react.element), key: null, ref: null, props: {…}, type: ƒ, …}
length: 2
__proto__: Array(0)

So I tried this... do you know how to access this date so that I can sort this array of posts by date? I know this isn't the normal way to access the props...

{bandTypes === 'all' ? allBands.map(band => {
    if(band.youtube.length > 0 && band.bandBio !== 'n/a' && band.bandGenre !== 'n/a'){
        return band.posts.map(post => {
            let currPost = convertPost(post, band)
            return currPost
        })
    }
}).sort((a, b) => b.props.post.date - a.props.post.date) : null}

I have also tried to sort the objects before doing the 'convertPost()' function... but the convert post function needs the 'band' parameter to work, which is only found in the map.

{bandTypes === 'all' ? allBands.map(band => {
    if(band.youtube.length > 0 && band.bandBio !== 'n/a' && band.bandGenre !== 'n/a'){
        return band.posts.map(post => {
            return post
        })
    }
}).sort((a, b) => b.date - a.date).forEach(post => {
    let currPost = convertPost(post, band)
    return currPost
}) : null}

Here is the convertPosts function

    const convertPost = (post, band) => {
        if(genre === 'Genre'){
            switch (post.type) {
                case "video":
                    return (
                        <VideoPosts key={post.postId} addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} link={post.data} band={band} post={post} _id={band._id} />
                    )
                case "text":
                    return (
                        <FeedPosts key={post.postId} addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} band={band} post={post} _id={band._id}/>
                    )   
                case "show":
                    return (
                        <ShowsPosts key={post.postId} addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} band={band} post={post} _id={band._id}/>
                    )
                case "band":
                    return (
                        <BandCard id={band._id} key={band.bandName} youtube={band.youtube} bandName={band.bandName} bandBio={band.bandBio} post={post} addFavorites={addFavorites} favorites={band.favorites} band={band} />
                    )
                case 'instagram':
                    return (
                        <InstagramPosts key={post.postId} addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} band={band} post={post} _id={band._id} />
                    )
                default: 
                    return null;
            }
        }else {
            if(band.bandGenre === genre ){
                switch (post.type) {
                    case "video":
                        return (
                            <VideoPosts addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} link={post.data} band={band} post={post} />
                        )
                    case "text":
                        return (
                            <FeedPosts addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} band={band} post={post} _id={band._id} />
                        )   
                    case "show":
                        return (
                            <ShowsPosts addFavorites={addFavorites} favorites={band.favorites} addRockOn={addRockOn} band={band} post={post} _id={band._id}/>
                        )
                    case "band":
                        return ( <BandCard id={band._id} key={band.bandName} youtube={band.youtube} bandName={band.bandName} bandBio={band.bandBio} addFavorites={addFavorites} favorites={band.favorites} band={band}/>
                        )
                    default: 
                        return null;
                }
            }
        }

    }

Post formats -

        {
            "type": "instagram",
            "data": "https://scontent-dfw5-1.xx.fbcdn.net/v/t51.2885-15/94831976_156494885869068_8673191033070945504_n.jpg?_nc_cat=103&_nc_sid=8ae9d6&_nc_ohc=BOk-_e1RMVwAX-w2ywz&_nc_ht=scontent-dfw5-1.xx&oh=f19acf2fab558ce0d2a79fba3d90db71&oe=5EE1F652",
            "link": "http://www.instagram.com/on_deband_booking",
            "date": "2020-04-28T16:32:40+0000",
            "postId": "18033963559249859",
            "rockOn": []
        },
        {
            "type": "text", //Really this is facebook
            "data": "Have you gotten that special someone, or...someone's, a valentine yet (we mean your favorite local bands)? This Valentine On DeBand is giving you a way to say thank you and show your appreciation to local bands and artists with a special gift (or you can gift it to yourself if you want, no harm in treating yo self)! Tomorrow is the big day, just follow this link: https://www.ondeband.com/happy-valentines/ \n\nDon't forget to follow us for all things music!\n*\n*\n*\n*\n#ondeband #band #music #valentines #specialsomeone #local #localmusic #localband #venue #rockshow #rock #country #metal #pop #punk #emo #love #gratitude #happyheartday",
            "link": "http://www.facebook.com/107460777308513_199513551436568",
            "date": "2020-02-13T16:14:34+0000",
            "postId": "107460777308513_199513551436568",
            "rockOn": []
        },
        {
            "type": "band",
            "data": "",
            "date": "2020-05-05T23:43:53.002Z",
            "postId": "c51295fe-14b0-4a19-9cc3-87da2a28c93f",
            "approved": null,
            "rockOn": []
        },
        {
            "type": "video",
            "data": "PuBqEdb464g",
            "date": "2020-05-05T22:40:23.958Z",
            "postId": "af28c07e-49cb-4b3c-9c6e-452112e1026a",
            "rockOn": []
        },
        {
            "date": "2020-05-05T22:54:59.673Z",
            "type": "show",
            "client": "email",
            "clientId": "5e8b54337d9c710ca6f117fa",
        }

回答1:


What you have to do first is reduce the allBands array into an array of all the posts, without any nesting. To keep both the post and band values, you can just combine them into a single object. Then you can sort it by date, however it is expressed in your data.

Doing anything with already created components is generally a bad idea and I would discourage it.

Here's the code:

{
    bandTypes === "all"
        ? allBands
              .reduce(
                  (allPosts, band) =>
                      allPosts.concat(
                          (band.youtube.length > 0 &&
                              band.bandBio !== "n/a" &&
                              band.bandGenre !== "n/a")
                              ? band.posts.map((post) => ({ post, band }))
                              : []
                      ),
                  []
              )
              .sort((a, b) => new Date(b.post.date) - new Date(a.post.date))
              .map(({ post, band }) => convertPost(post, band))
        : null;
}

You can find more information about reduce here.




回答2:


Why not sort the objects first before mapping to post components?

{
bandTypes === "all"
  ? allBands
      .map((band) => {
        if (
          band.youtube.length > 0 &&
          band.bandBio !== "n/a" &&
          band.bandGenre !== "n/a"
        ) {
          return band.posts;
        }
      })
      .sort((a, b) => b.date - a.date)
      .map((post) => {
        let currPost = convertPost(post, band);
        return currPost;
      })
  : null;
}


来源:https://stackoverflow.com/questions/61755267/can-you-sort-an-array-of-react-components-accessing-info-of-react-componenet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!