Cuando intento ejecutar este código y aparece el siguiente error.
Advertencia: no se puede llamar a setState en un componente que aún no está montado. Esto no es operativo, pero podría indicar un error en su aplicación. En su lugar, asigne a this.state directamente o defina un state = {}; propiedad de clase con el estado deseado en el componente Api.
¿Qué debo hacer para solucionar el problema?
class Api extends Component { constructor(props){ super(props) this.state = { data: [], } } async componentDidMount(){ this.apiCall() } async apiCall() { let resp = await fetch(URL) let respJson = await resp.json() this.setState({data:respJson.data.statistics}) } } export default function App(){ const api = new Api() api.componentDidMount() return ( <View> <ScrollView style={styles.center}> <Text>{api.state.data.time}</Text> </ScrollView> </View> ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', padding: 20, alignItems: 'center', padding: 15, }, title: { padding: 30, }, })Después de usar la solución Federkun, aparece este nuevo error, soy nuevo con JS, así que estoy un poco perdido.
Intenté usar una función asíncrona pero sigo mostrando el error.
Failed building JavaScript bundle. SyntaxError: C:\Users\yup\Documents\GitHub\LEARN_REACT\App.js: Unexpected reserved word 'await'. (54:19) 52 | 53 | React.useEffect(() => { > 54 | let resp = await fetch(URL) | ^ 55 | let respJson = await resp.json() 56 | setData({data:respJson.data.statistics})Api no es realmente un Component de reacción. Sin función de renderizado. Y necesitaría usarlo como parte de su jsx, no así.
Pero, hay una primitiva útil que puede contener estado: ganchos.
function useApi() { const [data, setData] = React.useState() React.useEffect(() => { async function load() { let resp = await fetch(URL) let respJson = await resp.json() setData({data:respJson.data.statistics}) } load() }, []) return data }Que puedes usar como
export default function App(){ const data = useApi() return ( <View> <ScrollView style={styles.center}> <Text>{data.time}</Text> </ScrollView> </View> ) }Esta es una extensión de la respuesta de @Federkun, que agrega algunos otros accesorios útiles y soluciona algunos problemas.
Puede reescribir su gancho useApi para,
function useApi() { const [data, setData] = React.useState(null); const [error, setError] = React.useState(null); const [loading, setLoading] = React.useState(false); React.useEffect(() => { const fetchData = async () => { setLoading(true); try { let resp = await fetch('URL'); // your backend url goes here let respJson = await resp.json(); setData(respJson); } catch (err) { setError(err); } finally { setLoading(false); } }; fetchData(); }, []); return { data, error, loading }; };y para usar,
export default function App() { const { data, loading, error } = useApi(); if (loading) return ( <View style={styles.container}> <Text>loading...</Text> </View> ); return ( <View style={styles.container}> {data && ( <Text>{JSON.stringify(data)}</Text> )} {error && ( <Text>{JSON.stringify(error)}</Text> )} </View> ); }Si todavía está confundido, puede verlo en acción en este refrigerio en vivo .