Issue
I would like to reload everything after going back to the screen. Like it is done in useEffect/componentDidMount
. Task which I'm trying to solve: I have some remotely based translations tool from which I fetch strings for everything like labels, buttons, hints for inputs and so on. On the "Settings" screen where I select another language I download from the api the new strings. And then after loading these new strings I would like to update my UI. I have such screen:
const LoginScreen = ({navigation}) => {
const [logInStr, setLogin] = useState('');
const [password, setPassword] = useState('');
const [reloadUI, setReload] = useState(false);
let commonData = CommonDataManager.getInstance();
const handleEmail = text => {
setLogin(text);
};
const handlePassword = text => {
setPassword(text);
};
const languagePress = () => {
setReload(true);
navigation.navigate('LanguageScr');
};
const updUI = () => {
};
useEffect(() => {
return navigation.addListener('focus', () => {
updUI();
});
}, [navigation]);
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => languagePress()}>
<Text style={styles.headerStyle}>Language</Text>
</TouchableOpacity>
<View style={[{flex: 1}, styles.elementsContainer]}>
<View style={{flex: 1, backgroundColor: '#EE2C38'}} />
<View style={{flex: 2, backgroundColor: '#FAA030'}} />
<View style={{flex: 3, backgroundColor: '#32B76C'}}>
<TextInput
style={styles.input}
underlineColorAndroid="transparent"
placeholder={commonData.getStrings()[11001]}
placeholderTextColor="#9a73ef"
autoCapitalize="none"
multiline={false}
onChangeText={handleEmail}
/>
<TextInput
style={styles.input}
underlineColorAndroid="transparent"
placeholder={commonData.getStrings()[10948]}
placeholderTextColor="#9a73ef"
autoCapitalize="none"
multiline={false}
secureTextEntry={true}
onChangeText={handlePassword}
/>
<TouchableOpacity style={styles.submitButton} onPress={() => ...}>
<Text style={styles.submitButtonText}>
{commonData.getStrings()[12078]}
</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
};
and here as you can see I have listener which will be triggered only after returning to this screen. I got to know about: this.forceUpdate();
but I got an error TypeError: undefined is not a function
in my updateUI
method. So, how I can do it? Maybe full reloading is not good solution and you will suggest me to use some state strings for such screen, but what if I use screen with more strings (>20) for example? So I will have to use 20 state elements? I think it is not also very logical, or I don't understand anything in it :(
Solution
So, I have managed to find the own solution for this task. As I said that for me it looks not good to make a lot of state variables for all fields. But I thought what if I will created one single map for all strings which will be equal for the apps' strings storage which will be updated after returning to the screen from which I went to the language screen. And below you can see the final colution:
const LoginScreen = ({navigation}) => {
....
const [map, setStrings] = useState(
CommonDataManager.getInstance().getStrings(),
);
....
const updUI = () => {
setStrings(CommonDataManager.getInstance().getStrings());
};
useEffect(() => {
return navigation.addListener('focus', () => {
updUI();
});
}, [navigation]);
.....
}
and all fields, labels and buttons titles are from this state map which will be updated :)
Answered By - Andrew
Answer Checked By - - Timothy Miller (ReactFix Admin)