How to output fetch request response in react native - react-native

I want to print out the response of my fetch request in react native.
How would I do this to get the response inside a Text?
function Nft() {
fetch(
"https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd"
);
return (
<View>
<Text style={style.header}>Bitcoin Price</Text>
</View>
);
}
export default Nft;

Define state variable like following
const[price,setPrice]=useState(0);
then replace fetch code by following
fetch('https://api.coingecko.com/api/v3/simple/price? ids=bitcoin&vs_currencies=usd')
.then((res)=>res.json())
.then((response)=>{
//your response is like this ,{"bitcoin":{"usd":18993.39}}
let price= response?.bitcoin?.usd;
setPrice(price)
})
.catch((error)=>{
//here you can manage errors
})
In your component you can right in this way
<Text>{price}<Text>

Please refer the following code
fetch('https://api.coingecko.com/api/v3/simple/price? ids=bitcoin&vs_currencies=usd')
.then((res)=>res.json())
.then((response)=>{
//here you can get your output of fetch in the response variable
//whatever data you want to show here save in state variable and
//use that state variable to display.
})
.catch((error)=>{
//here you can manage errors
})
**In your component you can right in this way
<Text>{your state variable}<Text>

Related

what is the difference between passing an object with a variable and a lone variable to a react native component?

My lack of success in this problem may be due to a lack of proper terminology when Googling it but nonetheless I am completely stumped. I am passing an onPress function to a custom component in react native. When I pass it by itself as:
export const AddMorePlants = ( onPress ) => {
return (
<TouchableHighlight
onPress={onPress}>
.
.
.
}
I get a this2.props.onPress is not a function error but when I have the exact same code except with the onPress passed within curly braces:
export const AddMorePlants = ({ onPress }) => {
return (
<TouchableHighlight
onPress={onPress}>
.
.
.
}
It Works!
Why does the second one work and not the first?
Sorry for a kind of basic question I just have been really Googling and cant figure it out. Thanks in advance and I can provide any more info if needed.
A functional component in React only has one parameter. The props. You can read more about it here
So what your first attempt at passing the onPress function actually looks like is:
export const AddMorePlants = (props) => {
return (
<TouchableHighlight onPress={props}/>
);
}
When the TouchableOpacity tries to execute the method, it hits the is not a function error because props is an object.
When you do:
export const AddMorePlants = ({onPress}) => {
return (
<TouchableHighlight onPress={onPress}/>
);
}
what you are doing is something called destructuring assignment and it's equivalent of doing:
export const AddMorePlants = (props) => {
const {onPress} = props;
return (
<TouchableHighlight onPress={onPress}/>
);
}
By putting the brackets inside the parentheses you are just doing a shorthand version of this destructuring assignment that we have mentioned.
Here's another version that would also work:
export const AddMorePlants = (props) => {
return (
<TouchableHighlight onPress={props.onPress}/>
);
}
As you can see there are many ways to access an object's property.
The important part is to remember that the props object is the only parameter passed into a functional component.
I hope this helps you understand what's going on there.
In the first function you need to pass only one param i.e onPress to your component while in second you are destructuring assignment so you are doing something like onPress = this.props.onPress and passing an object of params.

Setting data returned by useQuery as state

I have been using client.query to get data from my database and setting states using useState.
Here's an example:
const [videos, setVideos] = useState([]);
client.query({ query: GET_VIDEOS })
.then(response => {
setVideos(response.data.videos);
})
However, this does not load 100% of the time. Usually, it doesn't load when I load the app for the first time in a while. I typically have to reboot in these situations.
This issue makes me want to look into useQuery instead of client.query.
However, the examples in the documentation only show how we can use useQuery to make direct changes in the components.
Example:
function Dogs({ onDogSelected }) {
const { loading, error, data } = useQuery(GET_DOGS);
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
return (
<select name="dog" onChange={onDogSelected}>
{data.dogs.map(dog => (
<option key={dog.id} value={dog.breed}>
{dog.breed}
</option>
))}
</select>
);
}
However, I don't want to make changes to the components right now. I would much rather query the data and then set the queried data as a state, using useState.
How would I best accomplish this? One idea that I had was to create a component that returns null but queries the data. It would look something like this:
function Videos() {
const { loading, error, data } = useQuery(GET_VIDEOS);
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
setVideos(data);
return null;
}
I was curious to hear what are best practices for such situations.
react-apollo's useQuery has an onCompleted as one of its options, so you can use it like
const { loading, error } = useQuery(GET_VIDEOS, {
onCompleted: (data) => setVideos(data)
});
the best practise would be to use the data directly, without setting the state.
you have only showed the calling of setState, somewhere in your component the video state variable is used right?
pass the fetched data directly there. you need not call "setVideos" to trigger the change. whenever the query result is changed the UI will be changed accordingly.
There is useLazyQuery if your use case is not to fetch the data upfront.

Passing Barcode Scanned Data to Second Screen

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>

Why use this.setState will cause Maximum update depth exceeded?

In my class component i fetch API from react-redux to render my view. So i set a loading flag like this:
render() {
const theData = this.props.theData;
if(this.props.loading) {
return (
// Show loading view
);
}
console.log('I am test message');
return (
// This is real view want to show
);
}
If i run this i can see my log show I am test message just one time, because i fetch my API succeed and re-render view then pass if(this.props.loading).
Now i want to use theData with this.setState, so i try it like this:
render() {
const theData = this.props.theData;
if(this.props.loading) {
return (
// Show loading view
);
}
console.log('I am test message');
// Here is what i try
this.setState({ theData });
return (
// This is real view want to show
);
}
I think this.setState will run just one time too. But when i run it i see the error Maximum update depth exceeded
Why ? I have no idea with the situation. And if i want to use this.setState with avoid this error which place should be the better way ?
Any help would be appreciated. Thanks in advance.
this.setState({ theData }); , calling this method will cause the component to be rendered again and that is why you are getting the error. Set the state with theData in the constructor or the API call. Also in constructor , do not use the setState method , directly assign it . Ex : this.state = {}

Importing Text from local json file in React native

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;
}