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

React Navigation:Drawer导航中Header与Screen如何共享状态?

Drawer Navigator自定义Header共享Screen状态的解决方法

问题根源

你现在的代码里,MyScreenHeader是作为Drawer.Screen的options.header传入的,它的渲染层级在MyScreenProvider外面——MyScreenProvider只包裹了MyScreen的内容,而Header是由导航器负责渲染的,不在这个Provider的覆盖范围内,所以useContext拿不到有效值,只能返回初始的null。

两种可行解决方案

方案1:把Context Provider提到导航器外层

让整个Drawer Navigator都处于MyScreenProvider的包裹下,这样Header和Screen就能共享同一个Context:

const MyScreenContext = createContext(null);

const MyScreenProvider = ({children})=>{
  const [state,setState] = useState("");
  return <MyScreenContext.Provider value={{state,setState}}>{children}</MyScreenContext.Provider>
}

const MyScreenHeader = ()=>{
 const { state, setState } = useContext(MyScreenContext);
 // 这里可以正常读写输入值了
 return (
   <View>
     <TextInput value={state} onChangeText={setState} placeholder="请输入内容" />
   </View>
 )
}

const MyScreen = ()=>{
 const { setState } = useContext(MyScreenContext);

 // 清空输入的方法
 const clearInput = () => setState("");

 return (
   <View style={{flex:1, justifyContent:'center', alignItems:'center'}}>
     <Button title="清空输入框" onPress={clearInput} />
     {/* 其他页面内容 */}
   </View>
 )
};

// 把Provider包在导航器外面
export default function App() {
  return (
    <MyScreenProvider>
      <DrawerNavigator>
        <Drawer.Screen
          name={"MyScreen"}
          component={MyScreen}
          options={{
            header: MyScreenHeader,
          }}
        />
        {/* 其他页面 */}
      </DrawerNavigator>
    </MyScreenProvider>
  )
}

方案2:在Screen内部动态设置Header(更推荐)

用navigation.setOptions在MyScreen内部动态生成Header,这样Header就处于Screen的状态作用域内,甚至不用Context就能直接传值:

// 直接给Header传状态和修改函数
const MyScreenHeader = ({inputValue, setInputValue})=>{
 return (
   <View>
     <TextInput value={inputValue} onChangeText={setInputValue} placeholder="请输入内容" />
   </View>
 )
}

const MyScreen = ({navigation})=>{
  const [inputValue, setInputValue] = useState("");

  // 组件挂载后动态设置Header
  useEffect(() => {
    navigation.setOptions({
      header: () => <MyScreenHeader inputValue={inputValue} setInputValue={setInputValue} />
    });
  }, [navigation, inputValue]);

  // 清空输入
  const clearInput = () => setInputValue("");

  return (
    <View style={{flex:1, justifyContent:'center', alignItems:'center'}}>
      <Button title="清空输入框" onPress={clearInput} />
    </View>
  )
};

// 导航器配置保持不变
<Drawer.Screen
  name={"MyScreen"}
  component={MyScreen}
/>

这个方案更轻量,不会因为单个页面的状态污染全局Context,适合这种单个页面Header和内容交互的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 12:04:54