Использовать метод и состояние функционального компонента с помощью React Navigation setOptions

Я использую setOptions API React Navigation v5 для настройки кнопок заголовка и функций доступа внутри функционального компонента:

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: …» на консоли.

Однако, когда я нажимаю кнопку заголовка и вызывается метод handleSubmit, я вижу "отправить - текст теперь: initialValue", независимо от моих изменений.

Я не вижу, что я могу делать неправильно здесь, пожалуйста, посоветуйте.

Версии: * react: 16.11.0 * react-native: 0.62.2 * @react-navigation/native: 5.5.1


person digitalbreed    schedule 13.06.2020    source источник


Ответы (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]);
person Guruparan Giritharan    schedule 13.06.2020
comment
Спасибо, это работает! Можете ли вы объяснить /зачем/ мне это нужно? Насколько я понимаю, это эффективно переустанавливает параметры навигации при каждом изменении text, но фактические параметры не меняются - нет /прямой/ зависимости от text. Поэтому я не могу понять, как это работает. - person digitalbreed; 13.06.2020
comment
Ну, я получил эту проблему и исправил таким же образом, по какой-то причине он не видит обновленное значение, т. к. я не знаю фактической причины :( - person Guruparan Giritharan; 13.06.2020
comment
Хорошо, не беспокойтесь, может быть, кто-то еще сможет запрыгнуть сюда. Я все равно отметил это как правильный ответ, поскольку он решил проблему. Спасибо еще раз! - person digitalbreed; 13.06.2020