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

Posted

技术标签:

【中文标题】使用堆栈导航在自定义标题之间传递文本输入【英文标题】:passing text input between custom header using stack navigation 【发布时间】:2021-09-15 00:15:43 【问题描述】:

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

一开始,SearchMain screen 出现了, 当自定义标题中的TextInput为onFocus时,出现SearchHistory screen, 当 TextInput 为 onSubmitEditing 或按下 SearchButton 时出现 SearchResult screen。

另外,我将键盘焦点设置为在切换屏幕时保持,并在我想关闭它时使用 Keyboard.discuss()。

但是,如果您在屏幕更改后立即在自定义标题中的 TextInput 中输入内容,它将在前一屏幕的 TextInput 中输入。

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

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

我应该怎么做才能解决这个问题? 单例表头、静态表头、表头值一致等各种搜索,都没有好的解决办法。

我最近开始学习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;

【问题讨论】:

【参考方案1】:

在标头中设置状态不是一个好的模式,相反,您应该将状态集中在组件中,然后使用 navigation.setOption 传递函数/状态值。

这样,您的标题将如下所示:

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 中的状态、功能和自定义标题:

// 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>
)

【讨论】:

您好,感谢您的建议,我能够解决这个问题。但是在我学习 React Native 的时候,我还有一个问题。大多数自定义标头都以这种方式实现吗?我和我一起学习的朋友想知道使用这么多功能来管理这些状态是否正确。你觉得在这种情况下使用 Redux 怎么样?谢谢! 使用最新版本的 react native,管理状态的最佳方法是使用上下文 reactjs.org/docs/context.html。不需要redux,你的代码会更干净。

以上是关于使用堆栈导航在自定义标题之间传递文本输入的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义导航中添加 viewwillappear 和 viewdidappear 之间的延迟?

如何在自定义按钮颤动中给 onPressed 一个方法

如何根据文本输入类型在自定义键盘中标记返回键

在自定义单元格(xib)中滚动时,UITextField 中的文本消失

如何在自定义llvm传递之间正确传递数据结构

如何在自定义 UITableView 中获取文本字段