Как вызвать обновление состояния с помощью React-Navigation?

В моем приложении React Native я пытаюсь изменить состояние и запустить повторный рендеринг компонента. Это должно быть сделано, когда NavBottom вызывает this.props.navigation.navigate('captureView') для перехода к CaptureView. Обновление состояния должно сбросить переменную состояния CaptureView фото обратно в исходное значение.

Как можно изменить состояние в React Native с react-navigation на navigate? https://reactnavigation.org/docs/en/navigation-actions.html

CaptureView является частью CaptureStack

import { createStackNavigator } from "react-navigation";

const CaptureStack = createStackNavigator({
    captureView: CaptureView,
    detailView: DetailView,
    reportView: ReportView,

});

const Tab = createBottomTabNavigator({
    capture: CaptureStack,
}, {
    initialRouteName: 'capture',
    tabBarComponent: NavBottom
});

CaptureView.js:

import { StackActions, NavigationActions, NavigationEvents } from 'react-navigation';

class CaptureView extends Component {
    static navigationOptions = {}

    constructor(props) {
        super(props);
        console.log("CaptureView: constructor(props)");
    }

    componentDidMount() { // called just once
        console.log("CaptureView: componentDidMount()");
        // this.setState = { // undefined???
        //     photo: null // this needs to be RESET
        // };
    }

    componentWillUnmount() {
        console.log("CaptureView: componentWillUnmount()");
    }

    async onButtonPress() {
        CameraService.takePicture().then((photo)=>{
            this.setState({
                photo: photo
            });

            // More actions

            this.props.navigation.navigate(
                "detailView",
                {
                    id: 'DetailView',
                    photo
                }
            );

        });
    }

    render() {
        return (
            <Camera
                cameraSetter={(cam) => {
                    CameraService.setCamera(cam)
                }}
                photo={this.state.photo}
            />
            <TouchableOpacity onPress={this.onButtonPress.bind(this)}>
                <Text>TAKE PHOTO</Text>
            </TouchableOpacity>
        );
    }
}

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

NavBottom.js:

export default class NavBottom extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <View>
                <TouchableOpacity onPress={() => this.props.navigation.navigate('captureView')}>
                    <Text>CAMERA</Text>
                </TouchableOpacity>
            </View >);
    }
}

Примечания

Я пробовал разные способы из документации ReactJS (не React Native), которые не удались:

  • https://reactjs.org/docs/react-component.html#componentdidmount - componentDidMount() кажется рекомендуемым способом в документации, но в моем приложении он вызывается ТОЛЬКО ОДИН РАЗ?
  • Даже когда componentDidMount() вызывается один раз в начале, но даже тогда this.setState() не определено. Странно, в документации написано, что он должен быть доступен

person Peter G.    schedule 23.09.2019    source источник


Ответы (2)


пробовали ли вы использовать события навигации для сброса состояния компонента CaptureView?

Я думаю, onWillFocus может помочь.

https://reactnavigation.org/docs/en/navigation-events.html

person Antonio Pellegrini    schedule 23.09.2019
comment
Должно сработать в вашем случае. В целом (экранные) компоненты будут оставаться смонтированными до тех пор, пока они существуют где-то в стеке, поэтому, когда вы вернетесь к этому экрану, componentDidMount не сработает. Но если вы используете navigation.goBack (), чтобы вытащить экран из стека, он фактически отключится, поэтому componentDidMount будет запущен в следующий раз, когда мы перейдем к экрану. - person Antonio Pellegrini; 23.09.2019

React Navigation не выполняет повторный рендеринг компонента в стеке, который находится в Tab Naviagtor, чтобы выполнить принудительный повторный рендеринг, чем вы можете использовать прослушиватель событий, подобный этому

 componentDidMount() {
        this._navListener = this.props.navigation.addListener('didFocus', () => {
         //perform any action you want, place your logic here
        });

    }

вы также можете использовать HOC withNavigation React Navigation, передавая свойство (isFocused) подключенному компоненту


componentDidUpdate(prevProps, prevState) {
  if(prevProps.isFocused !== this.props.isFocused){
//place your desired logic here
}

}

Использование withNavigation

import { withNavigationFocus } from 'react-navigation';
 ...
 ...
 ...

export default withNavigationFocus(YourComponent)



person Anwar Gul    schedule 23.09.2019