You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Expo:数据获取与状态变更后如何触发页面重渲染

问题分析与解决方案

核心问题

页面无法自动重渲染的关键原因是冗余本地state导致Redux状态更新无法同步到视图:你通过useSelector获取了Redux中的用户数据,却额外将其复制到本地statecurrentProfilePage中,异步赋值过程导致视图无法及时响应Redux状态变化;同时加载状态判断依赖本地state,进一步加剧了渲染延迟。

具体优化点

  1. 移除冗余本地state:直接使用useSelector返回的Redux数据,无需通过currentProfilePage中转
  2. 简化Effect逻辑:删除不必要的state同步Effect,减少异步更新带来的不一致
  3. 修复加载状态管理:在数据请求开始/结束时更新isLoading,精准控制加载提示

修改后的代码

import { StatusBar } from 'expo-status-bar';
import { Button, StyleSheet, Text, TextInput, View, ScrollView, Image, FlatList, RefreshControl} from 'react-native';
import React, {useState, useEffect} from 'react'
import Icon from 'react-native-vector-icons/Feather';
import IconV from 'react-native-vector-icons/FontAwesome5';
import IconM from 'react-native-vector-icons/MaterialCommunityIcons';
import { useNavigation } from '@react-navigation/core';
import { useDispatch, useSelector } from 'react-redux';


import Header from '../src/components/Header';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { auth } from '../firebase';
import { updateProfile } from "firebase/auth";
import * as profilePageAction from '../redux/actions/profilePageAction';



const MyProfileScreen = props => {

  const [userEmail, setUserEmail] = useState();
  const [userName, setUserName] = useState();
  const [isLoading, setIsLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);

  const user = auth.currentUser;  
  const navigation = useNavigation();
  const dispatch = useDispatch();
  const FirebaseID = user.uid;

  // 直接使用Redux中的用户数据,无需中转到本地state
  const profilePage = useSelector(state => state.profilePage.profilePages.find(page => page.FirebaseID === FirebaseID));    

  useEffect(() =>{
    // 请求开始时标记加载状态
    setIsLoading(true);
    dispatch(profilePageAction.fetchProfilePages())
      .then(() => {
        // 请求成功后关闭加载状态
        setIsLoading(false);
        if(profilePage){
          setUserEmail(profilePage.Email);
        }
      })
      .catch(err => {
        console.log(err);
        // 请求失败也需关闭加载状态
        setIsLoading(false);
      });
  }, [dispatch, FirebaseID]);

  // 当Redux中用户数据变化时,同步更新本地邮箱状态(可选,视图可直接用profilePage.Email)
  useEffect(() =>{
    if(profilePage){
      setUserEmail(profilePage.Email);
    }
  }, [profilePage])
   
  return (
    <View style={styles.container}>
      <View style={styles.emailContainer}>
        {/* 基于加载状态和Redux数据判断渲染内容 */}
        {isLoading ? <Text style={styles.email}>Loading Data...</Text> :
          profilePage ? <Text>{profilePage.Email}</Text> : <Text style={styles.email}>未找到用户数据</Text>
        } 
      </View>  
    </View>              
  );
}


const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  emailContainer:{
    backgroundColor: '#000000',
    height: '15%',
    padding: 10
  },
  list:{
    shadowColor: 'black',   
    shadowOpacity: 0.25,
    shadowOffset: {width: 0 , height: 2},
    shadowRadius: 8,
    borderRadius: 10,
    backgroundColor: 'white',
    elevation: 5,
    height: 300,
    width: 200,
    margin: 10
  },
  email: {
    fontSize: 15,
    color: 'gray'
  }
});

export default MyProfileScreen;

额外说明

  • Redux的useSelector会自动订阅状态变化,当profilePages更新时组件会自动重渲染,无需手动同步到本地state
  • 加载状态isLoading需在请求全周期内明确设置,避免加载提示异常显示
  • 视图可直接使用profilePage.Email,无需额外存储到userEmail本地state,可进一步简化代码

内容的提问来源于stack exchange,提问作者Osman Elsoz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:10:32