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

问题描述 投票:0回答:3

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

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

reactjs react-native react-hooks react-navigation
3个回答
0
投票

您可以用这种方式做

  const onFocusScreen = useCallback(event => {

  console.log(text);

  }, []);

  useEffect(() => {
  navigation.addListener('focus', onFocusScreen);

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

0
投票

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

0
投票

@ 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 */);
    };
  }, []);

  ...
}
© www.soinside.com 2019 - 2024. All rights reserved.