React-Native中无需页面跳转,点击按钮传递文本至另一屏幕
嘿,作为React Native新手,这种不跳转页面却跨屏幕同步数据的需求其实挺常见的——毕竟不是所有数据传递都需要页面跳转~不用navigate的话,核心思路就是让两个屏幕共享同一个状态源,下面给你几个实用的方案,从简单到复杂都有:
1. 状态提升(适合简单场景:两个屏幕属于同一个父组件)
如果你的两个屏幕是同一个父组件下的子组件(比如在一个页面里分上下两部分,或者是同一个导航容器的兄弟项但逻辑简单),直接把状态提到父组件里管理是最省事的:
父组件(ParentComponent.js)
import { useState } from 'react'; import { View, StyleSheet } from 'react-native'; import ScreenA from './ScreenA'; import ScreenB from './ScreenB'; export default function ParentComponent() { // 共享状态存在父组件 const [sharedText, setSharedText] = useState("初始文本"); return ( <View style={styles.container}> {/* 把更新状态的方法传给ScreenA */} <ScreenA onSendText={setSharedText} /> {/* 把共享文本传给ScreenB */} <ScreenB displayText={sharedText} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, paddingVertical: 20 } });
发送数据的ScreenA.js
import { View, Button, TextInput, StyleSheet } from 'react-native'; import { useState } from 'react'; export default function ScreenA({ onSendText }) { const [inputText, setInputText] = useState(""); return ( <View style={styles.screenContainer}> <TextInput placeholder="输入要发送的文本" value={inputText} onChangeText={setInputText} style={styles.input} /> <Button title="发送到ScreenB" onPress={() => onSendText(inputText)} /> </View> ); } const styles = StyleSheet.create({ screenContainer: { flex: 0.5, justifyContent: 'center', alignItems: 'center' }, input: { borderWidth: 1, padding: 10, width: 250, marginBottom: 20, borderRadius: 8 } });
接收数据的ScreenB.js
import { View, Text, StyleSheet } from 'react-native'; export default function ScreenB({ displayText }) { return ( <View style={styles.screenContainer}> <Text style={styles.text}>来自ScreenA的文本:{displayText}</Text> </View> ); } const styles = StyleSheet.create({ screenContainer: { flex: 0.5, justifyContent: 'center', alignItems: 'center' }, text: { fontSize: 18, color: '#333' } });
2. Context API(适合中小型项目:跨层级/跨导航的屏幕)
如果你的两个屏幕不在同一个父组件下(比如底部导航的不同Tab页面),用React的Context API来做全局状态共享就很合适,不用引入额外库:
第一步:创建Context(DataContext.js)
import { createContext, useState, useContext } from 'react'; // 创建Context const DataContext = createContext(); // 写一个Provider组件,用来包裹整个App,提供共享状态 export function DataProvider({ children }) { const [sharedText, setSharedText] = useState("初始文本"); return ( <DataContext.Provider value={{ sharedText, setSharedText }}> {children} </DataContext.Provider> ); } // 封装一个自定义Hook,方便组件获取Context export function useData() { return useContext(DataContext); }
第二步:在App.js里包裹导航
import { DataProvider } from './DataContext'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import ScreenA from './ScreenA'; import ScreenB from './ScreenB'; const Tab = createBottomTabNavigator(); export default function App() { return ( // 用DataProvider包裹整个导航容器,让所有屏幕都能访问共享状态 <DataProvider> <NavigationContainer> <Tab.Navigator> <Tab.Screen name="发送页" component={ScreenA} /> <Tab.Screen name="接收页" component={ScreenB} /> </Tab.Navigator> </NavigationContainer> </DataProvider> ); }
第三步:修改ScreenA和ScreenB
ScreenA.js(发送数据)
import { View, Button, TextInput, StyleSheet } from 'react-native'; import { useState } from 'react'; import { useData } from './DataContext'; export default function ScreenA() { const { setSharedText } = useData(); // 获取更新状态的方法 const [inputText, setInputText] = useState(""); return ( <View style={styles.container}> <TextInput placeholder="输入文本" value={inputText} onChangeText={setInputText} style={styles.input} /> <Button title="发送到接收页" onPress={() => setSharedText(inputText)} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center' }, input: { borderWidth: 1, padding: 12, width: 280, marginBottom: 20, borderRadius: 8 } });
ScreenB.js(接收数据)
import { View, Text, StyleSheet } from 'react-native'; import { useData } from './DataContext'; export default function ScreenB() { const { sharedText } = useData(); // 获取共享的文本 return ( <View style={styles.container}> <Text style={styles.text}>收到的内容:{sharedText}</Text> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center' }, text: { fontSize: 20, fontWeight: '500', color: '#222' } });
3. Redux Toolkit(适合复杂大型项目)
如果你的项目有很多跨页面的状态需要管理,Redux Toolkit是更专业的选择,它简化了传统Redux的繁琐配置:
第一步:安装依赖
npm install @reduxjs/toolkit react-redux
第二步:创建Store和Slice
textSlice.js(定义状态和操作)
import { createSlice } from '@reduxjs/toolkit'; const initialState = { value: "初始文本", }; export const textSlice = createSlice({ name: 'text', initialState, reducers: { // 定义更新文本的方法 updateText: (state, action) => { state.value = action.payload; }, }, }); // 导出操作方法 export const { updateText } = textSlice.actions; // 导出reducer给Store用 export default textSlice.reducer;
store.js(配置Store)
import { configureStore } from '@reduxjs/toolkit'; import textReducer from './textSlice'; export const store = configureStore({ reducer: { text: textReducer, }, });
第三步:在App.js里包裹Provider
import { Provider } from 'react-redux'; import { store } from './store'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import ScreenA from './ScreenA'; import ScreenB from './ScreenB'; const Tab = createBottomTabNavigator(); export default function App() { return ( <Provider store={store}> <NavigationContainer> <Tab.Navigator> <Tab.Screen name="发送页" component={ScreenA} /> <Tab.Screen name="接收页" component={ScreenB} /> </Tab.Navigator> </NavigationContainer> </Provider> ); }
第四步:修改ScreenA和ScreenB
ScreenA.js(发送数据)
import { View, Button, TextInput, StyleSheet } from 'react-native'; import { useState } from 'react'; import { useDispatch } from 'react-redux'; import { updateText } from './textSlice'; export default function ScreenA() { const dispatch = useDispatch(); // 获取dispatch方法 const [inputText, setInputText] = useState(""); return ( <View style={styles.container}> <TextInput placeholder="输入文本" value={inputText} onChangeText={setInputText} style={styles.input} /> <Button title="发送" onPress={() => dispatch(updateText(inputText))} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center' }, input: { borderWidth: 1, padding: 12, width: 280, marginBottom: 20, borderRadius: 8 } });
ScreenB.js(接收数据)
import { View, Text, StyleSheet } from 'react-native'; import { useSelector } from 'react-redux'; export default function ScreenB() { // 从Store里获取文本状态 const sharedText = useSelector(state => state.text.value); return ( <View style={styles.container}> <Text style={styles.text}>收到的内容:{sharedText}</Text> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center' }, text: { fontSize: 20, fontWeight: '500', color: '#222' } });
总结一下:
- 简单父子组件用状态提升
- 中小型跨页面用Context API
- 大型复杂项目用Redux Toolkit
这些方案都不需要页面跳转,就能实时同步两个屏幕的数据~
内容的提问来源于stack exchange,提问作者Alexandra
相关产品推荐
相关产品推荐

