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

如何将React Navigation头部输入框的值传递至search/index页面?

实现方法

这里提供两种实用方案来获取header中搜索框的输入内容:

方案一:使用React Context跨组件共享状态

适合需要在多个组件中复用搜索状态的场景,步骤如下:

  1. 创建搜索状态的Context
// contexts/SearchContext.js
import { createContext, useContext, useState } from 'react';

const SearchContext = createContext();

export function SearchProvider({ children }) {
  const [searchText, setSearchText] = useState('');

  return (
    <SearchContext.Provider value={{ searchText, setSearchText }}>
      {children}
    </SearchContext.Provider>
  );
}

export function useSearch() {
  return useContext(SearchContext);
}
  1. 在根组件中包裹Provider
    修改你的Layout组件,用SearchProvider包裹Stack:
import { Stack } from 'expo-router';
import { SearchProvider } from '../contexts/SearchContext';
import { SearchBar } from '../components/SearchBar';

export default function Layout() {
  return (
    <SearchProvider>
      <Stack>
        <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
        <Stack.Screen
          name="search/index"
          options={{
            headerTitle: () => <SearchBar />,
          }}
        />
      </Stack>
    </SearchProvider>
  );
}
  1. 修改SearchBar组件使用Context
// components/SearchBar.js
import { TextInput, StyleSheet } from 'react-native';
import { useSearch } from '../contexts/SearchContext';

export function SearchBar() {
  const { searchText, setSearchText } = useSearch();

  return (
    <TextInput
      style={styles.input}
      value={searchText}
      onChangeText={setSearchText}
      placeholder="搜索..."
    />
  );
}

const styles = StyleSheet.create({
  input: {
    height: 40,
    borderColor: '#ccc',
    borderWidth: 1,
    borderRadius: 8,
    paddingHorizontal: 12,
    backgroundColor: '#fff',
    flex: 1,
  },
});
  1. 在search/index页面获取输入内容
// app/search/index.js
import { View, Text } from 'react-native';
import { useSearch } from '../../contexts/SearchContext';

export default function SearchPage() {
  const { searchText } = useSearch();

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>当前搜索内容:{searchText}</Text>
    </View>
  );
}

方案二:通过navigation.setOptions传递回调(仅单页面使用)

如果只需要在search/index页面获取搜索内容,可以直接在页面内定义状态,动态控制header:

  1. 修改search/index页面
// app/search/index.js
import { View, Text } from 'react-native';
import { useState, useEffect } from 'react';
import { useNavigation } from 'expo-router';
import { SearchBar } from '../../components/SearchBar';

export default function SearchPage() {
  const [searchText, setSearchText] = useState('');
  const navigation = useNavigation();

  useEffect(() => {
    // 动态设置headerTitle,传入输入变更回调
    navigation.setOptions({
      headerTitle: () => (
        <SearchBar
          value={searchText}
          onChangeText={setSearchText}
        />
      ),
    });
  }, [navigation, searchText]);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>当前搜索内容:{searchText}</Text>
    </View>
  );
}
  1. 调整Layout中的配置
    去掉Layout里对search/index的headerTitle配置,让页面自行控制:
import { Stack } from 'expo-router';

export default function Layout() {
  return <Stack>
    <Stack.Screen
      name="(tabs)"
      options={{ headerShown: false }}
    />
    <Stack.Screen
      name="search/index"
      // 移除原有headerTitle配置
    />
  </Stack>;
}
  1. 调整SearchBar为受控组件
// components/SearchBar.js
import { TextInput, StyleSheet } from 'react-native';

export function SearchBar({ value, onChangeText }) {
  return (
    <TextInput
      style={styles.input}
      value={value}
      onChangeText={onChangeText}
      placeholder="搜索..."
    />
  );
}

const styles = StyleSheet.create({
  input: {
    height: 40,
    borderColor: '#ccc',
    borderWidth: 1,
    borderRadius: 8,
    paddingHorizontal: 12,
    backgroundColor: '#fff',
    flex: 1,
  },
});

内容的提问来源于stack exchange,提问作者Kos-Mos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:30:14