首页 > 解决方案 > 在 Safari 中使用排序

问题描述

我在 Safari 中按日期排序帖子时遇到问题。在 Chrome 中一切正常。

首先,我从我的 API 中获取所有帖子。然后我从 facebook api 获取一些帖子。这些在一个数组中组合在一起。

如果我发布新帖子,它会将其发布到 facebook 并将帖子发回以显示在我的网站上。在 chrome 中,它会自动按日期排序并添加到正确的位置。在 safari 中,所有新的 facebook 帖子都被添加到数组的末尾 - 未按日期排序。它们出现在列表的末尾。

即使我刷新页面,“新”帖子仍保留在列表的末尾。

好的,这是一个更奇怪的方面。如果我切换回 chrome,它会正确排序它们。当我切换回 safari 时,它们会被正确排序。这几乎就像 chrome 中发生的任何事情都会重置 safari 中对列表进行排序的能力。

这是我的排序功能

{clicked === 'feed' ? (posts.sort((a, b) => 
                new Date(b.date) - new Date(a.date)
            ).map((post) => {
                    return <div key={post.postId} >{convertPost(post)}</div>
                })) : null }

这是我获取帖子的方式-

    const getPosts = async () => {
        console.log('getting posts on posts')
        const token = await getTokenSilently();

        try {
            //Get ODB Posts
            let response = await fetch(`/api/autoquotegenerators/${_id}`, {
                headers: {
                    Authorization: `bearer ${token}`,
                    "Content-Type": "application/json; charset=UTF-8",
                }
            });
            const responseData = await response.json()
            setBand(responseData)
            setYoutube(responseData.youtube)
            setFavorites(responseData.favorites)
            setFbData(responseData.fbData)
            if(!responseData.fbData){
                setPosts(responseData.posts)
            }

            let fbDataTemp = responseData.fbData

            if(responseData.fbData && !responseData.fbData.instaId){
                //Get Only FB and ODB Posts
                //Get Fb Posts
                let fbFormattedPosts = []
                response = await fetch(`https://graph.facebook.com/${fbDataTemp.pageId}/feed?access_token=${fbDataTemp.pageAccessTokenLong}`)
                let fbPosts = await response.json()
                fbPosts.data.forEach(post => {
                    if(post.message){
                        let fbPostObject = {
                            type: 'text',
                            data: post.message,
                            link: `http://www.facebook.com/${post.id}`,
                            date: post.created_time,
                            postId: post.id,
                            rockOn: []
                        }
                        fbFormattedPosts.push(fbPostObject)
                    }
                })

                //Set All Posts 
                setPosts([ 
                    ...responseData.posts, 
                    ...fbFormattedPosts
                        .filter(({postId}) => 
                        !responseData.posts
                            .find(post => post.postId == postId)),
                ])

            }else if(responseData.fbData && responseData.fbData.instaId){
                //First Get Fb Posts
                let fbFormattedPosts = []
                response = await fetch(`https://graph.facebook.com/${fbDataTemp.pageId}/feed?access_token=${fbDataTemp.pageAccessTokenLong}`)
                let fbPosts = await response.json()
                fbPosts.data.forEach(post => {
                    if(post.message){
                        let fbPostObject = {
                            type: 'text',
                            data: post.message,
                            link: `http://www.facebook.com/${post.id}`,
                            date: post.created_time,
                            postId: post.id,
                            rockOn: []
                        }
                        fbFormattedPosts.push(fbPostObject)
                    }
                })

                //Get IG Media Ids 
                let instaFormattedPosts = []
                response = await fetch(`https://graph.facebook.com/v7.0/${fbDataTemp.instaId}/media?access_token=${fbDataTemp.pageAccessTokenLong}`)
                let instaPosts = await response.json()

                //Get IG Posts 
                for (let i=0 ; i< instaPosts.data.length ; i++) {
                    const instaId = instaPosts.data[i];
                    const instaResponse = await fetch(`https://graph.facebook.com/${instaId.id}?fields=id,media_url,timestamp,username&access_token=${fbDataTemp.pageAccessTokenLong}`)
                    let instaPostRendered = await instaResponse.json()

                    let instaPostObject = {
                        type: 'instagram',
                        data: instaPostRendered.media_url,
                        link: `http://www.instagram.com/${instaPostRendered.username}`,
                        date: instaPostRendered.timestamp,
                        postId: instaPostRendered.id,
                        rockOn: [],
                    }
                    instaFormattedPosts.push(instaPostObject)
                }

                //Set All Posts 
                setPosts([ 
                    ...responseData.posts, 
                    ...fbFormattedPosts
                    .filter(({postId}) => 
                        !responseData.posts
                            .find(post => post.postId == postId)),
                ...instaFormattedPosts
                        .filter(({postId}) => 
                                !responseData.posts
                                    .find(post => post.postId == postId))
                ])
            }
        } catch (error) {
            console.log(error)
        }
    }

好的...发现了更多有趣的事情 - '.sort' 在 Safari 上不起作用

我在我的排序函数中添加了 1 : -1。然后它最初正确地对 safari 数组进行排序,然后开始一遍又一遍地反转它。铬的作品。

{clicked === 'feed' ? (posts.sort((a, b) => 
                new Date(b.date) > new Date(a.date) ? 1 : -1
            ).map((post) => {
                    return <div key={post.postId} >{convertPost(post)}</div>
                })) : null }

标签: reactjssortingsafarifetch

解决方案


基于这个答案,Safari 有(或至少有)用 4 位数字表示时区的日期,没有分号。不幸的是,Facebook 以这种格式返回日期“2020-02-13T16:14:34+0000”,所以这一定是你的问题。

要修复它,您可以在处理来自 Facebook(以及使用此格式的其他服务)的帖子时添加冒号

fbPosts.data.forEach(post => {
    if(post.message){
        let fbPostObject = {
            type: 'text',
            data: post.message,
            link: `http://www.facebook.com/${post.id}`,
            date: post.created_time.slice(0, -2) + ':' + post.created_time.slice(-2),
            postId: post.id,
            rockOn: []
        }
        fbFormattedPosts.push(fbPostObject)
    }
})

推荐阅读