I am wondering how the common way is to import a huge text to a View. In my case i am developing a React Native App for Android and iOS, and on one of my Views i want to present the "Terms of Use" document. Now when i just import/copy paste it into a Text Component it just can´t be the right solution, especially when i need to use localization to present the needed language. How would i "import" this Text-Block so it is nice formatted and i don´t need to put everything into my View:
<View style={styles.container}>
<Text style={styles.text}> |JSON - Text-file, with about 600 words -> Terms of Use document |</Text>
</View>
You can use:
import file from './config/TermsAndCondition.json';
then you can treat it as a javascript object:
file.description
I'd to it as JSON, especially if you need to bring some other (meta)data with the text. Where fetch(url) is called on componentWillMount and <Text>{this.state.hugeText}</Text> component is populated:
As a concept:
constructor(props) {
super(props);
this.state = {
hugeText: ''
};
}
componentWillMount() {
fetch('myText.json')
.then((res) => res.json())
.then((data) => {
this.setState({
hugeText: data.something
});
});
}
I tried fetch but it didn't work (wasn't able to find the file).
I tried this instead, and it worked:
// at top of file
var jsonData = require('./myfile.json');
// inside component definition
render() {
let deepProp = jsonData.whatever;
}
Related
I am having a problem updating a state. I fetch a JSON result using an address set as 'newurl' and display contents in a FlatList. It all works good and I have a button that when clicked updates the 'newurl' state and reloads the data. The problem is it needs clicking twice to update the state? I have tried putting the setState in a different class but does not work Also I have can not make new 'newurl' to include the state of 'newuser'
The onclick to update the state and reload the data which updates after 2 clicks is :
onPress = () => {
this.setState({
newurl: 'https://www.newtesturl'
}),
fetch(this.state.newurl)
.then(response => response.json())
.then((response)=> {
this.setState({loading: false,list: response.data})
})
}
The problem with making the 'newurl' string when updating it, I cannot seem to add another data state into it. If I use the code below, the 'newurl' is pretty much as is it, without adding the 'newuser' state?
this.setState({
loading: true,
newurl: 'https://www.example.com/userid={this.state.newuser}'
});
Its really annoying because when I add that into a direct url like below it works?
<Image source={{uri: `https://www.example.com/userid={this.state.newuser}`}} />
This is how I am setting up my props in case it makes a differnce? :
type Props = {};
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.state = { list: [], loading: false, newuser: '10101', newurl: '' };
}
Sorry if I have not explained it that well but if you need anything clarifying please ask, thanks
State Updates May Be Asynchronous. See here for more info.
Second issue is because you don't use template string there. See here for more info.
I'm trying to pass the data I have received from scanning a barcode. I'm able to print the data using JSON.stringify(data) and the data is being passed but I just can't seem to display it.
Passing the data successfully with:
_handleBarCodeRead = data => {
Alert.alert(
'Scan successful!',
JSON.stringify(data)
);
const { navigate } = this.props.navigation;
navigate('KnownProduct', {data})
};
Attempting to render the data on this page:
render(){
const { navigate } = this.props.navigation;
return(
<View style={styles.container}>
<Text>{this.props.navigation.state.params.data.toString}</Text>
</View>
);
I know the navigation works correctly because if I hard-code the value the screen does navigate after scanning a barcode and display the hard-coded value. However, I think I'm trying to call the data incorrectly with: this.props.navigation.state.params.data.toString but having no luck figuring out how to display the passed data.
Any react native experts able to help a newbie?
OK.... So I figured it out... thanks to one commenter who pointed out I should pass the data like so:
navigate('KnownProduct', {data: data})
And then what was missing in the redirection page was:
<Text>{this.props.navigation.state.params.data.data}</Text>
data.data got me!
Try this :
navigate('KnownProduct', {data:JSON.stringify(data)})
AND
<Text>{this.props.navigation.state.params.data}</Text>
try this
navigate('KnownProduct', {data:data.data})
<Text>{this.props.navigation.getParam('data')}</Text>
I am building an app where the users are prompted to choose their language the first time they launch the app. The language is then stored locally using AsyncStorage.
Every time the app launches the language is retrieved from storage and saved into the global.lang variable to be used by all components:
AsyncStorage.getItem('settings', (err, item) => {
global.lang = item.lang;
});
When I use the global.lang variable in the render() method in any component everything seems to be ok. However I run into trouble when trying to use the same variable when initializing my navigators:
const TabNavigator = createBottomTabNavigator(
{
Home: {
screen: HomeScreenNavigator,
navigationOptions:{
title: strings['en'].linkHome, --> this works
}
},
News: {
screen: NewsScreen,
navigationOptions:{
title: strings[global.lang].linkNews, --> this fails
}
}
});
I believe that this because the value is not retrieved from AsyncStorage by the time that the navigators are constructed. If I set the global.lang manually (eg. global.lang = 'en';) it seems to be OK, but not when I try to retrieve it from the storage.
Is there something that I am missing? Could I initialize the navigator with a default language and change the title later based on the value retrived?
Any help would be greatly appreciated.
The navigators are constructed in the app launch. So you would need to use some placeholder text and use the method described here where you change all screen titles based on the screen key...
Or... this sounds insane and i have never tried it. But you can use a loading screen where you retrieve the languaje settings. then... via conditional rendering you "render" a navigator component . Idk if it would work the same way , but you can try it. below some code that i just created for this purpose
export default class MainComponent extends React.Component {
constructor(props) {
super(props);
this.state = { hasLanguage:false};}
componentDidMount(){
this.retrieveLanguage()
}
async retrieveLanguage(){
//await AsyncStorage bla bla bla
//then
this.setState({hasLanguage:true})
}
render() {
return (
{
this.state.hasLanguage?
<View>
//this is a view that is rendered as a loading screen
</View>:
<Navigator/>//this will be rendered, and hence, created, when there is a language retrieved
}
);
}
}
Again. I don't know if react navigation creates the navigator at render . If so. When it creates a navigator , there should be the languaje to be used there
My android app is loading string data from a js file that is looking like this:
module.exports = {
DATA: {
firstdata: 'data',
seconddata: 'data2'},
};
What I want to do, is change content of this file using text input with
onChangeText={(text) => data.DATA.firstdata.setState({text})}
But it tells me that "undefined is not a function".
These are my first attempts with text inputs. Any help will be appreciated :)
it seems you are trying to implement different concepts. You are trying to change js file using setState function, which is a function provided by react to change data in local component state. So, in your case, data.DATA.firstdata should be just a string, that doesn't know what setState function is. But, according to an error, it seems you are not even importing this DATA variable.
What you can do is set this data to your local state when component is mounted, and then mutate this local state with setState function.
...
import { DATA } from './path/to/the/file'
class MyComponent extends Component {
constructor(props) {
super(props)
this.state = {
firstdata: DATA.firstdata,
seconddata: DATA.seconddata,
};
}
render() {
return (
...
<TextInput onChangeText={(text) => this.setState({firstdata: text})}>
)
}
}
I am trying to create a button which is displaying and hiding a navigation menu on click. I am using Redux to get the current state into the Component, but something is not working with the onPress function.
When pressing the button I want to check the current state of this.state.showNavigation (can be true/false) but I am getting an "undefined is not an object" error immediately after clicking the button.
I think I am running into a lifecycle issue here. I already tried to ship around this via setting the state in componentWillMount like that:
componentWillUpdate(){
this.state = NavigationStore.getState();
}
Anyway that didn't help. Some advise is much appreciated. Thanks!
Heres my code:
class NavigationButton extends React.Component {
constructor(props, context) {
super(props, context);
this.state = NavigationStore.getState();
NavigationStore.subscribe(() => {
this.setState(NavigationStore.getState());
});
// alert(this.state.showNavigation);
}
render() {
return (
<TouchableOpacity
onPress={this.handlePressButton}
style={navigationButtonStyles.button}>
<Image source={buttonImage} />
</TouchableOpacity>
);
}
handlePressButton() {
if(this.state.showNavigation){
NavigationStore.dispatch({
type: 'HIDE_NAVIGATION',
});
}
else{
NavigationStore.dispatch({
type: 'SHOW_NAVIGATION',
});
}
}
};
I was using a pretty strange approach, I did not use the react-redux package for the whole thing and couldn't connect my store. I deep dived into https://github.com/bartonhammond/snowflake and got it solved, the snowflake example was really helpful to understand the basics!