通过 React Navigation setOptions 使用功能组件的方法和状态

Use method and state of functional component with React Navigation setOptions

我正在使用 React Navigation v5 的 setOptions API 来自定义我的 header 按钮和功能组件内的访问功能:

import React, { useState, useLayoutEffect } from 'react';
import { View, TouchableOpacity, TextInput } from 'react-native';

export default ({ navigation }) => {

    const [text, setText] = useState('initialValue');

    console.log('render - text is now: ' + text);

    useLayoutEffect(() => {
        navigation.setOptions({
            headerRight: () => (
                <TouchableOpacity onPress={handleSubmit}>
                    <View style={{marginRight: 18, borderWidth: 2, borderColor: 'white', borderRadius: 17.5, width: 35, height: 35}}>
                        {/* FontAwesome icon omitted for brevity */}
                    </View>
                </TouchableOpacity>
            )
        });
    }, [navigation]);

    const handleSubmit = () => {
        console.log('submit - text is now: ' + text);
    };

    return (
        <View style={{flex: 1, padding: 20}}>
            <TextInput
                style={{width: '100%'}}
                multiline
                autoGrow
                value={text}
                onChangeText={text => setText(text)}
            />
        </View>
    );
};

当我使用此组件并更改文本时,我可以在控制台上看到正确的 "render - text is now: ..." 输出。

但是,当我单击 header 按钮并调用 handleSubmit 方法时,我看到 "submit - text is now: initialValue",而不管我的更改如何。

我没看出来我这里可能做错了什么,请指教。

版本: * 反应:16.11.0 * react-native: 0.62.2 * @react-navigation/native: 5.5.1

您必须将文本作为 useLayoutEffect 的依赖项才能工作

  React.useLayoutEffect(() => {
        navigation.setOptions({
            headerRight: () => (
                <TouchableOpacity onPress={handleSubmit}>
                    <View style={{marginRight: 18, borderWidth: 2, borderColor: 'white', borderRadius: 17.5, width: 35, height: 35}}>
                        {/* FontAwesome icon omitted for brevity */}
                    </View>
                </TouchableOpacity>
            )
        });
    }, [navigation,text]);