【问题标题】:React Navigation 5 headerRight button function called doesn't get updated statesReact Navigation 5 headerRight按钮函数调用没有更新状态
【发布时间】:2020-06-07 23:40:46
【问题描述】:

在以下简化示例中,用户使用 TextInput 更新标签状态,然后单击标题中的“保存”按钮。在提交函数中,当请求标签状态时,它返回原始值 '' 而不是更新后的值。

需要对导航标题右键按钮进行哪些更改才能解决此问题?

注意:当保存按钮在渲染视图中时,一切都按预期工作,只是在标题中时不是。

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

export default function EditScreen({navigation}){
  const [label, setLabel] = useState('');

  useLayoutEffect(() => {
      navigation.setOptions({
        headerRight: () => (
          <TouchableWithoutFeedback onPress={submit}>
            <Text>Save</Text>
          </TouchableWithoutFeedback>
        ),
      });
    }, [navigation]);

  const submit = () => {
    //label doesn't return the updated state here
    const data = {label: label}
    fetch(....)
  }

  return(
    <View>
      <TextInput onChangeText={(text) => setLabel(text) } value={label} />  
    </View>
  )

}

【问题讨论】:

    标签: react-native react-navigation react-navigation-v5


    【解决方案1】:

    标签应该作为 useLayouteffect 的依赖项传递,这将使钩子在更改时运行

      React.useLayoutEffect(() => {
          navigation.setOptions({
            headerRight: () => (
              <TouchableWithoutFeedback onPress={submit}>
                <Text>Save</Text>
              </TouchableWithoutFeedback>
            ),
          });
        }, [navigation,label]);
    

    【讨论】:

      【解决方案2】:

      Guruparan 对这个问题的回答是正确的,尽管我想让该解决方案更适用于具有许多 TextInput 的屏幕。

      为了实现这一点,我添加了一个称为保存的附加状态,当单击完成时将其设置为 true。这会触发调用 useEffect 挂钩并因此触发提交。

      export default function EditScreen({navigation}){
        const [label, setLabel] = useState('');
        const [saving, setSaving] = useState(false);
      
        useLayoutEffect(() => {
            navigation.setOptions({
              headerRight: () => (
                <TouchableWithoutFeedback onPress={() => setSaving(true)}>
                  <Text>Done</Text>
                </TouchableWithoutFeedback>
              ),
            });
          }, [navigation]);
      
          useEffect(() => {
            // Check if saving to avoid calling submit on screen unmounting
            if(saving){
              submit()
            }
          }, [saving]);
      
          const submit = () => {
            const data = {label: label}
            fetch(....)
          }
      
          return(
            <View>
              <TextInput onChangeText={(text) => setLabel(text) } value={label} />  
            </View>
          )
      
      }
      

      【讨论】:

      • 我相信这个答案要好得多,因为它避免了每次标签更改时都运行 useEffect,很好的答案@dan
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多