首页 > 解决方案 > 如何在反应导航监听器中访问当前状态?

问题描述

我正在使用 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>
    );
  }
}

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

标签: reactjsreact-nativereact-hooksreact-navigation

解决方案


好的,我找到了使用 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>
  );
}

推荐阅读