I'm creating a React native app for a covid form I'm getting the data from a Json so I've used fetch and .then to get the actually json with the question and save it on a QuestionsState, but when I try to filter the data and get the individual question to save that on a QuestionState, that is not showing on the view, but when I console.log that and press ctrl s to save en vs code, the individual question appears
the questions code is this
import { StyleSheet, Text, View, Button } from 'react-native'
import React, {useState, useEffect} from 'react'
const url = 'https://raw.githubusercontent.com/alejoduke52/covidForm/main/covid-19.json'
const Questions = () => {
const [covidQuestions, setCovidQuestions] = useState([{}])
const [individualQuestion, setIndividualQuestion] = useState([])
const [loading, setLoading] = useState(true)
const [countId,setCountId] = useState(1)
useEffect(() => {
console.log("cargando use effect")
getData()
},[])
useEffect(() => {
console.log("cargando use effect data unica")
getQuestion(1)
},[countId])
const getData = () =>{
fetch(url)
.then(resp => resp.json())
.then(data => {
setCovidQuestions(data)
getQuestion(1)
})
}
const getQuestion = (id) => {
setIndividualQuestion(covidQuestions.filter(Question => Question.id === id))
console.log(individualQuestion)
setLoading(false)
}
const handlerNextQuestion = () => {
console.log("jasdjasjdas")
console.log(individualQuestion)
//getQuestion(countId)
setCountId(countId 1)
}
return (
<View>
{
loading ? <Text style={styles.loading}>LOADING</Text> : (
<View key={0}>
<Text>hello {individualQuestion.question}</Text>
</View>
)
//jsx
}
<Button title="Cargando s" onPress={() => handlerNextQuestion()} />
</View>
);
}
export default Questions
const styles = StyleSheet.create({
loading: {
fontSize: 40
}
})
It is very strange cause when I first render the app the state is empty but only when I press ctrl s, it shows
CodePudding user response:
individualQuestion
state is an array you have to use it like
Option 1:
hello {individualQuestion[0].question}
Option 2:
setIndividualQuestion(covidQuestions.filter(Question => Question.id === id)[0])
CodePudding user response:
You can use getQuestion(1, data)
instead of getQuestion(1)
.
You can pass data to getQuestion
function
const getData = () =>{
fetch(url)
.then(resp => resp.json())
.then(data => {
setCovidQuestions(data)
getQuestion(1, data)
})
}
const getQuestion = (id,data) => {
setIndividualQuestion(data.filter(Question => Question.id === id))
...
...
...
}
CodePudding user response:
Please check the below code It will give you full functionality:
import { StyleSheet, Text, View, Button } from 'react-native'
import React, { useState, useEffect } from 'react'
const url = 'https://raw.githubusercontent.com/alejoduke52/covidForm/main/covid-19.json'
const Questions = () => {
const [covidQuestions, setCovidQuestions] = useState([])
const [individualQuestion, setIndividualQuestion] = useState()
const [loading, setLoading] = useState(true)
const [countId, setCountId] = useState(1)
useEffect(() => {
console.log("cargando use effect")
getData()
}, [])
const getData = () => {
fetch(url)
.then(resp => resp.json())
.then(data => {
if (data.length > 0) {
setCovidQuestions(data)
console.log("Data", data)
getQuestion(1, data)
}
})
}
const getQuestion = (id, data) => {
console.log(data)
let question = data.find(Question => Question.id === id)
console.log("Question", question)
setIndividualQuestion(question)
setLoading(false)
}
const handlerNextQuestion = () => {
setCountId(countId 1)
getQuestion(countId 1, covidQuestions)
}
return (
<View>
{
loading ? <Text style={styles.loading}>LOADING</Text> : (
<View key={0}>
<Text>hellO</Text>
{individualQuestion != undefined ?
<View>
<Text>{JSON.stringify(individualQuestion)}</Text>
<Text>Question: {individualQuestion.question}</Text>
</View> : null}
</View>
)
}
<Button title="next" onPress={() => handlerNextQuestion()} />
</View>
);
}
export default Questions
const styles = StyleSheet.create({
loading: {
fontSize: 40
}
})
Hope You will like it! :)
CodePudding user response:
Here there are two problem which I see
First problem is you are trying to access covidQuestions
immediately after setCovidQuestions
inside getQuestion(1)
function, since setting state in react is always an asynchronous event and takes some time to update the state value. So basically you should not call getQuestion(1)
immediately after setCovidQuestions
.
Second, problem I see with the filter you are using, since filter always return an array of filtered questions, even if there is one question, so you can never access individualQuestion
like {individualQuestion.question}
, since its an array.
My solution to the first problem would be to remove getQuestion(1)
after setCovidQuestions
inside fetch API call and instead you can actually add covidQuestions
as dependency to your useEffect which runs on change of countId
like below
JSX
useEffect(() => {
console.log("cargando use effect data unica")
getQuestion(1)
},[countId, covidQuestions])
And for your second problem related to filter mechanism, you can do something like this, while rendering
JSX
<View key={0}>
<Text>hello {individualQuestion[0].question}</Text>
</View>