更新状态时,React Native组件未重新呈现

t98cgbkg  于 2023-01-05  发布在  React
关注(0)|答案(2)|浏览(175)

我在React Native应用中有一个组件,它显示待定好友列表。该组件向API发出GET请求,以检索待定好友列表,然后使用useEffect钩子Map列表,并将每个好友呈现为Pressable组件。我还使用useFocusEffect钩子在屏幕呈现时发出get请求。
下面是该组件的相关代码:

const Pending = () => {
  const [pendingFriends, setPendingFriends] = useState(null)
  let pendingFriendsRender = []

  useEffect(() => {
    if (pendingFriends !== null) {
      for(let i = 0; i < pendingFriends.length; i++) {
        pendingFriendsRender.push(
          <Pressable  key={i} style={styles.friend}>
            <Text style={styles.friendText}>{pendingFriends[i].username}</Text>
          </Pressable>
        )
      }
    }
  }, [pendingFriends])

  useFocusEffect(
    useCallback(() => {
      async function fetchData() {
        const accessToken = await AsyncStorage.getItem('accessToken')
        try {
          const res = await instance.get('/pending_friends', {
            headers: { authorization: `Bearer ${accessToken}`},
          })
          setPendingFriends(res.data)
        } catch (error) {
          console.log(error.response.status)
        }
      }
      fetchData()
    }, [])
  )

  return(
    <View style={styles.friendsContainer}>
      {pendingFriendsRender}
    </View>
  )
}

我试过使用一个空数组作为useEffect钩子的第二个参数,但是这个方法不起作用。我也试过删除useEffect钩子,这样if语句和for循环就可以放在没有钩子的组件的顶部,这个方法起作用了,但是在组件渲染之后我不能用这种方法更新它。我检查了API,它返回了正确的数据。

vnzz0bqm

vnzz0bqm1#

第一个useEffect其实并不需要,你可以在JSX中Map你的状态,只要状态改变,组件就会被重新呈现:

// Need a default here, could also set some loading state when fetching your data
  if(pendingFriends === null) {
    return <>Loading...</>
  }

  return(
    <View style={styles.friendsContainer}>
      {pendingFriends.map((friend, i) => {
          return (
            <Pressable key={friend.id} style={styles.friend}>
              <Text style={styles.friendText}>{friend.username}</Text>
            </Pressable>
          )
        })}
    </View>
  )

另外要记住,不推荐使用索引作为键,这可能会导致意想不到的错误和问题,而应该使用唯一的字符串键(如上所示)。
React: using index as key for items in the list

ix0qys7i

ix0qys7i2#

pendingFriendsRender的状态应为:

const [pendingFriendsRender, setPendingFriendsRender] = useState([])

代替

let pendingFriendsRender = []

然后克隆数组,这样就失去了对对象的引用,并添加新元素

const newPendingFriendsRender = [...pendingFriendsRender, newElement]

或者您可以使用FlatList来简化此操作。

相关问题