使用堆栈导航在自定义 header 之间传递文本输入

passing text input between custom header using stack navigation

我想使用堆栈导航的自定义 header 连接 SearchMain、SearchHistoryList 和 SearchResult 屏幕。

起初,SearchMain screen出现了, 当自定义 header 中的 TextInput 为 onFocus 时, SearchHistory screen 出现, SearchResult screen 在 TextInput 处于 onSubmitEditing 或按下 SearchButton 时出现。

另外,我设置了切换屏幕时保持键盘焦点,想关闭时使用Keyboard.discuss()

但是,如果您在屏幕切换后立即在自定义 header 中的 TextInput 中输入内容,它将在前一屏幕的 TextInput 中输入。

我认为这是因为三个屏幕不共享一个自定义 header!!每个header被创建,键盘焦点在上一个屏幕!!

我希望所有屏幕使用相同的 header,或者 header 的值一致。

我应该怎么做才能解决这个问题? singleton header, static header, value consistent header 各种搜索,都没有很好的解决办法

最近开始学习React Native,所以对自己的方法不是很清楚,也欢迎完全不同的方法~~

下面是我的代码,谢谢。

const Stack = createStackNavigator();

function NavigationBar({navigation}){
const [query, setQuery] = React.useState('');

function changeSearchQuery(text : string) : void {
    setQuery(text);
}

function deleteSearchQuery() : void {
    setQuery("");
}

return(
    <InputView>
        <BackIcon onPress={() => {navigation.goBack()
                        Keyboard.dismiss()}}>
            <Icon name="arrow-back-ios" size={widthPercentage(24)} color="#666666"/>
        </BackIcon>
        <InputText
            keyboardType="default"
            maxLength={100}
            onChangeText={(str) => setQuery(str)}
            value = {query}
            placeholder="검색어 입력"
            placeholderTextColor="#E9E9E9"
            returnKeyType="search"
            onFocus={() => navigation.navigate("SearchHistory", {changeSearchQuery:changeSearchQuery})}
            onSubmitEditing={() => {navigation.navigate("SearchResult", {changeSearchQuery:changeSearchQuery})
                            Keyboard.dismiss()}}
            allowFontScaling= {false}
        />

        { query.length > 0 && 
            <DeleteIcon onPress={() => deleteSearchQuery()}>
                <Icon name="clear" size={widthPercentage(20)} color="#666666"/>
            </DeleteIcon>
        }
        
        <SearchIcon onPress={() => {navigation.navigate("SearchResult")
                                Keyboard.dismiss()}}>
            <Icon name="search" size={widthPercentage(20)} color="#666666"/>
        </SearchIcon>

        <Line></Line>
    </InputView>
);
}

export const Search = () =>{
return (
    <Stack.Navigator initialRouteName="SearchMain" keyboardHandlingEnabled={false} screenOptions={{header:props => <NavigationBar navigation={props.navigation}/>}}>
        <Stack.Screen name="SearchMain" component={SearchMain} options={{animationEnabled: false}}/>
        <Stack.Screen name="SearchHistory" component={SearchHistory} options={{animationEnabled: false}}/>
        <Stack.Screen name="SearchResult" component={SearchResult} options={{animationEnabled: false}}/>
        <Stack.Screen name="SearchFilter" component={SearchFilter} options={{headerShown: false}}/>
    </Stack.Navigator>
);
}

export default Search;

在 header 中设置状态不是一个好的模式,相反你应该将状态集中在你的组件中,然后使用 navigation.setOption 传递 functions/state 值。

这样您的 header 将如下所示:

function NavigationBar({
    query,
    onFocus,
    onChangeText,
    onPressBackIcon,
    onSubmitEditing,
    onDeleteSearch,
    onSearch
    }){

return(
    <InputView>
        <BackIcon onPress={onPressBackIcon}>
            <Icon name="arrow-back-ios" size={widthPercentage(24)} color="#666666"/>
        </BackIcon>
        <InputText
            keyboardType="default"
            maxLength={100}
            onChangeText={onChangeText}
            value = {query}
            placeholder="검색어 입력"
            placeholderTextColor="#E9E9E9"
            returnKeyType="search"
            onFocus={onFocus}
            onSubmitEditing={onSubmitEditing}
            allowFontScaling= {false}
        />

        { query.length > 0 && 
            <DeleteIcon onPress={onDeleteSearch}>
                <Icon name="clear" size={widthPercentage(20)} color="#666666"/>
            </DeleteIcon>
        }
        
        <SearchIcon onPress={onSearch}>
            <Icon name="search" size={widthPercentage(20)} color="#666666"/>
        </SearchIcon>

        <Line></Line>
    </InputView>
);
}

你将在 SearchMainScreen 中拥有你的状态、你的功能和你的自定义 header:

// remember headerMode='none' in screen option
const SearchMainScreen = () => {
const [query, setQuery] = React.useState('');
const onFocus = () => {}
...

return (
<View>
<NavigationBar
  onFocus={onFocus}
  query={query}
  ...
/>
{
      (isFocus && !query) ? 
      <SearchHistoryComponent/> : 
      (isFocus && query) ? 
      <SearchResultComponent/> :
      <List/>
}
</View>
)
}