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

React Native基于React Navigation实现类组件间对象传递与列表更新

解决方案

方案1:最小改动实现:通过路由参数回传更新(适合快速跑通流程)

你现在已经在newMedScreen的提交方法里把新的药物对象通过路由参数传回Home页面了,只需要补全参数接收和全局状态更新的逻辑即可:

步骤1:修正App.js中addMed方法的写法

你原来的写法直接修改原state数组,React可能无法触发重新渲染,调整为符合不可变更新原则的写法:

addMed = (med) => {
  // 用展开运算符生成新数组,确保state更新能触发重渲染
  this.setState({ meds: [...this.state.meds, med] }, () => {
    console.log(this.state.meds)
  })
}

步骤2:把addMed方法传递给HomeScreen

修改App.js,将路由组件移到App内部,通过初始参数传递全局方法:

class App extends Component{
  state = {
    meds: []
  }

  addMed = (med) => {
    this.setState({ meds: [...this.state.meds, med] }, () => {
      console.log(this.state.meds)
    })
  }

  // 把路由组件放在App内部,可直接访问实例方法
  MyStack = () => {
    return (
      <Stack.Navigator 
      screenOptions={{
        headerShown: false
      }}>
        {/* 把addMed和全局药物列表通过初始参数传给Home */}
        <Stack.Screen 
          name="Home" 
          component={HomeScreen} 
          initialParams={{ 
            addMed: this.addMed,
            meds: this.state.meds
          }} 
        />
        <Stack.Screen name="New Medication" component={newMedScreen} />
      </Stack.Navigator>
    );
  }

  render(){
    return(
      <NavigationContainer>
        <this.MyStack/>
      </NavigationContainer>
    );
  }
}

步骤3:在HomeScreen中监听传回的药物对象并更新全局状态

修改HomeScreen.js,添加生命周期方法监听路由参数变化:

class HomeScreen extends React.Component{
  // 组件更新时检测是否有新传回的药物数据
  componentDidUpdate(prevProps) {
    const currentMed = this.props.route.params?.med
    const prevMed = prevProps.route.params?.med
    // 仅当药物参数变化时触发更新,避免重复添加
    if (currentMed && currentMed !== prevMed) {
      this.props.route.params.addMed(currentMed)
      // 清空参数防止重复触发
      this.props.route.params.med = undefined
    }
  }

  render(){
    const meds = this.props.route.params?.meds || []
    return(
    <View style={styles.container}>
        <ScrollView style={styles.content}>
            <Heading message="meds" />
            {/* 渲染药物列表 */}
            {meds.map(item => <Text key={item.id}>{item.med} - 剂量:{item.dose}</Text>)}
        </ScrollView>
        <Button title="新增药物" onPress={() => this.props.navigation.navigate('New Medication')} />
    </View>
)}
}

方案2:规范的单一数据源实现:使用React Context(推荐长期使用)

如果希望后续维护更简单,不需要路由来回传参,直接用React Context共享全局状态是最优选择,完全符合你单一数据源的要求:

步骤1:创建全局Context

新建MedContext.js文件:

import React from 'react'
const MedContext = React.createContext()
export default MedContext

步骤2:在App.js中用Provider包裹路由,提供全局状态和方法

修改App.js:

import MedContext from './MedContext'

const Stack = createStackNavigator();
function MyStack() {
  return (
    <Stack.Navigator 
    screenOptions={{
      headerShown: false
    }}>
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="New Medication" component={newMedScreen} />
    </Stack.Navigator>
  );
}

class App extends Component{
  state = {
    meds: []
  }

  addMed = (med) => {
    this.setState({ meds: [...this.state.meds, med] })
  }

  render(){
    return(
      <NavigationContainer>
        {/* 所有子孙组件都可以访问Provider里的全局状态和方法 */}
        <MedContext.Provider value={{
          meds: this.state.meds,
          addMed: this.addMed
        }}>
          <MyStack/>
        </MedContext.Provider>
      </NavigationContainer>
    );
  }
}

步骤3:在NewMedScreen中直接调用全局新增方法

修改NewMed.js的提交逻辑,不需要再通过路由回传参数:

import MedContext from './MedContext'

class newMedScreen extends React.Component{
  // 声明使用全局Context
  static contextType = MedContext
    
  state = {
    med: '',
    dose: ''
  }
  onChangeText = (key, value) => {
    this.setState({ [key]: value })
  }

  submit = () => {
    if (this.state.med === '' || this.state.dose === ''){ 
        alert('请填写所有字段')
        return
    }
    const med = {
      med: this.state.med,
      dose: this.state.dose,
      id: uuidV4(),
    }
    // 直接调用全局方法更新App状态
    this.context.addMed(med)
    this.setState({
      med: '',
      dose: ''
    }, () => {
      this.props.navigation.navigate('Home')
    })
  }
  // 其余渲染逻辑保持原有即可
}

步骤4:在HomeScreen中直接读取全局药物列表渲染

修改HomeScreen.js:

import MedContext from './MedContext'

class HomeScreen extends React.Component{
  static contextType = MedContext

  render(){
    const { meds } = this.context
    return(
    <View style={styles.container}>
        <ScrollView style={styles.content}>
            <Heading message="meds" />
            {/* 直接遍历全局列表渲染 */}
            {meds.map(item => (
              <Text key={item.id} style={styles.text}>
                {item.med} - 剂量:{item.dose}
              </Text>
            ))}
        </ScrollView>
        <Button title="新增药物" onPress={() => this.props.navigation.navigate('New Medication')} />
    </View>
)}
}

注意:你的newMedScreen组件名首字母需要改成大写NewMedScreen,否则React会识别为普通DOM标签导致报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:54:06