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

如何从React Native屏幕向Stack Navigator传递参数?

如何向Stack Navigation栈导航器传递参数(含函数)

当然可以。针对你需要把屏幕内useState保存的表单值和API调用函数传给栈导航器的需求,以下是几种实用方案:


方案1:通过navigation.getParent()动态修改导航器配置

这是最直接的方式,适合给导航器的头部按钮绑定屏幕内的函数。利用navigation.getParent()获取父导航器实例,再调用setOptions()更新导航器的头部组件,直接传入屏幕内的函数(该函数会闭包当前的表单状态值)。

示例代码:

import { useState } from 'react';
import { View, TextInput, Button } from 'react-native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function FormScreen({ navigation }) {
  const [formValues, setFormValues] = useState({ email: '', password: '' });

  // 绑定了当前表单状态的API调用函数
  const submitForm = async () => {
    try {
      await fetch('https://api.example.com/submit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(formValues),
      });
      // 提交后的逻辑,比如导航回上一页
      navigation.goBack();
    } catch (err) {
      console.error('提交失败:', err);
    }
  };

  // 组件挂载后,给父导航器设置头部右侧按钮
  useState(() => {
    navigation.getParent().setOptions({
      headerRight: () => (
        <Button title="提交" onPress={submitForm} color="#2196F3" />
      ),
    });
  }, [formValues, navigation]);

  return (
    <View style={{ padding: 16, gap: 12 }}>
      <TextInput
        value={formValues.email}
        onChangeText={(text) => setFormValues(prev => ({ ...prev, email: text }))}
        placeholder="输入邮箱"
        autoCapitalize="none"
        style={{ borderBottomWidth: 1, paddingVertical: 8 }}
      />
      <TextInput
        value={formValues.password}
        onChangeText={(text) => setFormValues(prev => ({ ...prev, password: text }))}
        placeholder="输入密码"
        secureTextEntry
        style={{ borderBottomWidth: 1, paddingVertical: 8 }}
      />
    </View>
  );
}

function AppStack() {
  return (
    <Stack.Navigator initialRouteName="Form">
      <Stack.Screen name="Form" component={FormScreen} options={{ title: '表单页面' }} />
    </Stack.Navigator>
  );
}

方案2:使用React Context共享状态与函数

如果你的导航器或多个组件都需要访问表单状态和提交函数,用React Context是更优雅的选择,避免props层层传递。

步骤1:创建Context

import { createContext, useContext, useState } from 'react';

const FormContext = createContext();

export function FormProvider({ children }) {
  const [formValues, setFormValues] = useState({ email: '', password: '' });

  const submitForm = async () => {
    try {
      await fetch('https://api.example.com/submit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(formValues),
      });
    } catch (err) {
      console.error('提交失败:', err);
    }
  };

  return (
    <FormContext.Provider value={{ formValues, setFormValues, submitForm }}>
      {children}
    </FormContext.Provider>
  );
}

export function useForm() {
  return useContext(FormContext);
}

步骤2:在导航器中消费Context

import { Button } from 'react-native';
import { createStackNavigator } from '@react-navigation/stack';
import { useForm } from './FormContext';

const Stack = createStackNavigator();

function CustomStackNavigator() {
  const { submitForm } = useForm();

  return (
    <Stack.Navigator
      screenOptions={{
        headerRight: () => (
          <Button title="提交" onPress={submitForm} color="#2196F3" />
        ),
        title: '表单页面'
      }}
    >
      <Stack.Screen name="Form" component={FormScreen} />
    </Stack.Navigator>
  );
}

步骤3:在屏幕组件中更新状态

import { View, TextInput } from 'react-native';
import { useForm } from './FormContext';

function FormScreen() {
  const { formValues, setFormValues } = useForm();

  return (
    <View style={{ padding: 16, gap: 12 }}>
      <TextInput
        value={formValues.email}
        onChangeText={(text) => setFormValues(prev => ({ ...prev, email: text }))}
        placeholder="输入邮箱"
        autoCapitalize="none"
        style={{ borderBottomWidth: 1, paddingVertical: 8 }}
      />
      <TextInput
        value={formValues.password}
        onChangeText={(text) => setFormValues(prev => ({ ...prev, password: text }))}
        placeholder="输入密码"
        secureTextEntry
        style={{ borderBottomWidth: 1, paddingVertical: 8 }}
      />
    </View>
  );
}

步骤4:在根组件中包裹Provider

import { NavigationContainer } from '@react-navigation/native';
import { FormProvider } from './FormContext';
import CustomStackNavigator from './CustomStackNavigator';

function App() {
  return (
    <NavigationContainer>
      <FormProvider>
        <CustomStackNavigator />
      </FormProvider>
    </NavigationContainer>
  );
}

方案3:使用Ref引用屏幕内的函数

如果表单状态完全封装在屏幕组件内部,不想暴露给外部,可以用React Ref来引用屏幕内的提交函数,再传递给导航器。

示例代码:

import { useState, useRef, useEffect } from 'react';
import { Button, View, TextInput } from 'react-native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();
const submitRef = useRef(null);

function FormScreen() {
  const [formValues, setFormValues] = useState({ email: '', password: '' });

  const submitForm = async () => {
    try {
      await fetch('https://api.example.com/submit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(formValues),
      });
    } catch (err) {
      console.error('提交失败:', err);
    }
  };

  // 将提交函数挂载到ref上
  useEffect(() => {
    submitRef.current = submitForm;
    return () => {
      submitRef.current = null;
    };
  }, [formValues]);

  return (
    <View style={{ padding: 16, gap: 12 }}>
      <TextInput
        value={formValues.email}
        onChangeText={(text) => setFormValues(prev => ({ ...prev, email: text }))}
        placeholder="输入邮箱"
        autoCapitalize="none"
        style={{ borderBottomWidth: 1, paddingVertical: 8 }}
      />
      <TextInput
        value={formValues.password}
        onChangeText={(text) => setFormValues(prev => ({ ...prev, password: text }))}
        placeholder="输入密码"
        secureTextEntry
        style={{ borderBottomWidth: 1, paddingVertical: 8 }}
      />
    </View>
  );
}

function AppStack() {
  return (
    <Stack.Navigator
      screenOptions={{
        headerRight: () => (
          <Button 
            title="提交" 
            onPress={() => submitRef.current?.()} 
            color="#2196F3" 
          />
        ),
        title: '表单页面'
      }}
    >
      <Stack.Screen name="Form" component={FormScreen} />
    </Stack.Navigator>
  );
}

方案选择建议

  • 简单场景(仅给头部按钮传函数):优先用方案1,代码量最少,无需额外封装;
  • 多组件共享状态/函数:用方案2,Context能更好地管理全局状态;
  • 状态完全封装在屏幕内:用方案3,避免状态暴露,保持组件独立性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:01:21