如何在React Navigation侦听器中访问当前状态?

时间:2020-05-17 20:54:29

标签: reactjs react-native react-hooks react-navigation

我正在使用react-navigation 5创建一个react-native应用程序。

假设我有一个这样的屏幕组件:

import {View, Text} from 'react-native';

function TextScreen({navigation}) {
  const [text, setText] = useState(null);

  useEffect(() => {
    setText('Some text.');
    navigation.addListener('focus', () => {
      console.log('focus');
      console.log(text); // this is always null :/
    });
  }, []);

  return (
    <View>
      <Text>{text || 'No text'}</Text>
    </View>
  );
}

我不知道为什么每个console.log(text)在每个焦点上都显示null值。我希望文字仅在第一焦点上null,但它始终会出现。

但是当我将此组件更改为类组件时,一切都按预期工作:

import {View, Text} from 'react-native';

class TextScreen extends React.Component {
  state = {
    text: null
  }

  componentDidMount() {
    this.setState({text: 'Some text'});
    this.props.navigation.addListener('focus', () => {
      console.log('focus');
      console.log(this.state.text); // this is null only in the first focus
    });
  }

  render() {
    return (
      <View>
        <Text>{this.state.text || 'No text'}</Text>
      </View>
    );
  }
}

在第一个版本中我做错什么了吗?

3 个答案:

答案 0 :(得分:2)

@erichio是否可以将 useEffect 更改为 useFocusEffect

import { RouteProp, useFocusEffect } from '@react-navigation/native'

function TextScreen({navigation}) {

  ....

  useFocusEffect(() => {
    setText('Some text.');
    navigation.addListener('focus', () => {
      console.log('focus');
      console.log(text); // this is always null :/
    });

    return () => {
      navigation.removeEventListener('focus',() => /* YOUR_LOGIC */);
    };
  }, []);

  ...
}

答案 1 :(得分:1)

好的,我找到了使用useRef钩子的解决方案: React useState hook event handler using initial state

所以我的情况应该是:

import {View, Text} from 'react-native';

function TextScreen({navigation}) {
  const [text, _setText] = useState(null);
  const textRef = useRef(text);
  const setText = newText => {
    textRef.current = newText;
    _setText(newText);
  };

  useEffect(() => {
    setText('Some text.');
    navigation.addListener('focus', () => {
      console.log('focus');
      console.log(textRef.current);
    });
  }, []);

  return (
    <View>
      <Text>{text || 'No text'}</Text>
    </View>
  );
}

答案 2 :(得分:0)

您可以通过这种方式

async