2

I have a screen using tab navigator. inside the app have drawer navigator. inside drawer, have some option to choose using radio button like option A, B, C. when I choose one option, supposedly it will be updated on main screen. but the problem is, main screen not re-render or refresh the state. is there any solution?

main screen

static navigationOptions = ({ navigationOptions, navigation }) => {
  return {
    title: '',
    headerStyle: {
      backgroundColor: '#025A75'
    },
    headerLeft: (
      <TouchableHighlight underlayColor='transparent' onPress={() => { 
        navigation.openDrawer() 
        }}>
        <View style={{flexDirection: 'row'}}>
            <Image
              source={require('../assets/image/exchange-line.png')}
              style={{marginLeft: Platform.OS === 'android' ? 15 : 15 }}
              resizeMode="contain"
            />
              <CustomText p center style={{marginLeft:15}}>Switch Account</CustomText>
        </View>
      </TouchableHighlight>
    )
    
  }
};
componentDidMount(){
  const { navigation } = this.props;
   this.focusListener = navigation.addListener("willFocus", () => {     
   this.refreshScreen();
   console.log('componentdidmount trigger')
  });
}

 refreshScreen(){
    console.log('refreshScreen trigger')
    this.setState({
     data: user.getAccountList(), 
     raw_data: user.getAccountList(), 
     currentAccountIndex: user.getCurrentAccountIndex(),
     prefer_account: user.getAccountList()[user.getCurrentAccountIndex()].memberID
    });
   console.log(this.state.currentAccountIndex)}

drawer screen

export default class SwitchAccountScreen extends React.Component {
    state = {
      data: [],
      currentAccountIndex: 0
    }

    _switchAccount(index){
      user.setCurrentAccountIndex(index);
      this.setState({currentAccountIndex: index});
      this.props.navigation.closeDrawer()
   }

  render() {
    ...
    <TouchableHighlight style={{borderWidth: 1, borderColor: '#ACACAC', borderRadius: 5, marginLeft: 25, marginRight: 35, marginBottom: 20}} underlayColor='transparent'
                            onPress={() => { this._switchAccount(key) }}
                          />
    ...
  }
}

when the drawer is closed. i want the main screen trigger the refreshScreen() to update the state.

Shah Amir
  • 33
  • 3

1 Answers1

0

This is a functionality of React Native Navigation. Where all the screens in a stack remain mounted. Hence, revisiting previous screens will not trigger a state update because of no mount occurring.

There are 3 solutions for this

1st Solution - UseFocusEffect

useFocusEffect(()=> {
    your code
})

This will trigger a re-render (State Update) whenever your screen is focused again.

2nd Solution - useIsFocused

import { useIsFocused } from '@react-navigation/native'

export default function App(){

const isFocused = useIsFocused()

    useEffect(() => {
        //Update the state you want to be updated
    } , [isFocused])
}

3rd Solution - Event Listeners

useEffect(()=>{
    const didBlurSubscription = this.props.navigation.addListener(
      'willBlur',
      payload => {
        console.debug('didBlur', payload);
      }
    );
    
    // Remove the listener when you are done
    return () => didBlurSubscription.remove();  
}
Vin Xi
  • 986
  • 2
  • 11