Saya memiliki array kompleks yang mengisi objek. (Tampilkan di bawah)

 const privateMessages = Array [
  Object {
    "_id": "607533d511a2301b204720ed",
    "chat": Array [
      Object {
        "_id": "6098ffd30a2f4287f92be018",
        "createdAt": "2021-05-10T09:41:39.683Z",
        "text": "G",
        "user": Object {
          "_id": "60716a38136f970ba4a0526e",
        },
      },
      Object {
        "_id": "6097b6e69f98cbf5ba6deaf8",
        "createdAt": "2021-05-09T10:18:36.972Z",
        "text": "ত",
        "user": Object {
          "_id": "60716f7cf3a75846ee1f5d38",
        },
      },
      Object {
        "_id": "6097b6aacd62683ba317965d",
        "createdAt": "2021-05-09T10:17:36.182Z",
        "text": "H",
        "user": Object {
          "_id": "60716a38136f970ba4a0526e",
        },
      }
    ],
    "pair": Array [
      Object {
        "_id": "60716a38136f970ba4a0526e",
        "firstName": "Sayan",
        "lastName": "Biswas",
      },
    ],
  },
]

Cukup sulit untuk memperbaruinya menggunakan setState hook , jadi saya memutuskan untuk menggunakan force Update untuk merender ulang komponen tetapi tidak berfungsi. Cara saya memperbarui status diberikan di bawah ini

privateMessages.forEach((i) => {
                    if (i.pair[0]._id == data.sender) {
                        i.chat.unshift(data.chatObj)
                    }
                })

Ini adalah kait forceUpdate yang saya gunakan

function useForceUpdate() {
    const [value, setValue] = useState(0); // integer state
    return () => setValue(value => value + 1); // update the state to force render
}

Cara saya menyebutnya

const forceUpdate = useForceUpdate()

Saya menggunakan kait forceUpdate() yang sama di bagian lain dari proyek saya dan berfungsi dengan baik tetapi saya tidak tahu mengapa itu tidak berfungsi dengan fungsi peta bersarang yang diberikan di bawah ini

Sunting :-

Banyak jawaban mengatakan kepada saya untuk tidak menggunakan forceUpdate jadi saya menghapusnya. Saya mencoba semua solusi yang diberikan dalam jawaban tetapi tidak ada yang berfungsi. Mendapatkan ide dari jawaban @Punisher , saya membuat solusi sendiri dari bagian pembaruan status tetapi aplikasi macet saat dijalankan.

socket.on("recieve-private-message", (data) => {
                setPrivateMessages(prevState => {
                    const privateMessagesCopy = JSON.parse(JSON.stringify(prevState))
                    privateMessagesCopy.forEach((i) => {
                        if (i.pair[0]._id == data.sender) {
                            i.chat.unshift(data.chatObj)
                        }
                    })
                    return privateMessagesCopy
                }                    
                )
            })

Seluruh kode:-

import React, { useState, useEffect, useContext } from 'react';
import { View, Text, TouchableOpacity, ScrollView } from 'react-native';
import AsyncStorage from "@react-native-async-storage/async-storage"
import API from '../api.js'
import { useNavigation } from '@react-navigation/native';
import { SocketObj } from "./Main"

function useForceUpdate() {
    const [value, setValue] = useState(0); // integer state
    return () => setValue(value => value + 1); // update the state to force render
}

const ChatScreen = () => {

    const navigation = useNavigation()

    let socket = useContext(SocketObj)

    let [privateMessages, setPrivateMessages] = useState([])

    let [userId, setUserId] = useState('')

    const forceUpdate = useForceUpdate()

    useEffect(
        () => {
            const fetchData = async () => {
                try {
                    const response = await API.get('get/chats', {
                        headers: {
                            'Content-Type': 'application/json',
                            "auth-token": await AsyncStorage.getItem("token")
                        }
                    })
                    setPrivateMessages(response.data.chatFriends)
                    setUserId(response.data.userId)
                } catch (err) {
                    console.log(err.response)
                }
            }
            fetchData()

            socket.on("recieve-private-message", (data) => {
                privateMessages.forEach((i) => {
                    if (i.pair[0]._id == data.sender) {
                        i.chat.unshift(data.chatObj)
                    }
                })
                forceUpdate()
            })
        }, []
    )


    useEffect(
        () => {
            console.log("changed")
        },[privateMessages]
    )

    return (<View>
        <ScrollView >
            {
                privateMessages.map(
                    (i) => i.pair.map(
                        (j) => {
                            return (
                                <>
                                    <TouchableOpacity
                                        key={j._id}
                                        onPress={() => {
                                            navigation.navigate("PrivateConversation", {
                                                chats: i.chat,
                                                userId: userId,
                                                socket: socket,
                                                name: j.firstName,
                                                recieverId: j._id
                                            })
                                        }
                                        } >
                                        <Text key={j._id} >{j.firstName + ' ' + j.lastName}</Text>
                                    </TouchableOpacity>
                                </>
                            )
                        }
                    )
                )
            }
        </ScrollView>
    </View>)
}

export default ChatScreen
0
SAYAN 10 Mei 2021, 12:59

3 jawaban

Jawaban Terbaik

Saya akan menghindari pola pembaruan paksa sebanyak mungkin. Saya tidak berpikir Anda membutuhkannya di sini. Meskipun saya tidak melihat ada yang salah, saya sarankan Anda mencoba dua opsi ini untuk membantu debug. Jika solusi ini tidak berhasil, maka ada hal lain yang sangat salah.

(1) Gunakan setState sebagai gantinya. Saat Anda memperbarui objek obrolan, buat salinan mendalamnya terlebih dahulu. Perbarui salinan dalam dengan metode Anda saat ini dan kemudian panggil setState(copy). Catatan: pastikan untuk menggunakan perpustakaan untuk menyalin dalam seperti lodash atau trik stringify (Apa cara paling efisien untuk mengkloning objek dalam JavaScript?)

(2) Gunakan reduksi sebagai gantinya. Bila Anda memiliki objek rumit seperti milik Anda, reduksi sangat umum digunakan. Ini mungkin solusi terbaik dalam hal praktik terbaik (pemeliharaan dan keterbacaan)

0
Punisher 10 Mei 2021, 23:10

Ubah fungsi soket Anda menjadi:

socket.on("recieve-private-message", (data) => {
  setPrivateMessages(prevState => prevState
     .map(privateMessage => {
        const [firstPair] = privateMessage.pair

        return firstPair._id !== data.sender
            ? privateMessage
            : ({
                ...privateMessage,
                chat: [
                    data.chatObj,
                    ...privateMessage.chat
                ]
            })
     })
  )
})
0
Jacek Pudysz 11 Mei 2021, 10:26

Saya pikir Anda tidak memperbarui status dalam fungsi Anda

Coba sesuatu seperti di bawah ini: -

socket.on("recieve-private-message", (data) => {
  const privateMessagesCopy = [...privateMessages]
  const updatedPrivateMessages = privateMessagesCopy.map((i) => {
    if (i.pair[0]._id == data.sender) {
      i.chat.unshift(data.chatObj)
    }
    return i;
  })
  setPrivateMessage([...updatedPrivateMessages]);
})

0
Priyank Kachhela 10 Mei 2021, 10:13