GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Expo Usa Função e sem Expo É Usada Classe

Tags: #<Tag:0x00007f9b0c40dd88> #<Tag:0x00007f9b0c40dc48>

Aprendi a usar o setState para renderizar novamente a classe herdeira de Component, a principal, mas usando Expo, numa função async, se digito, nomeDaFunçãoPrincipal(), nada acontece.

Como chamar a função principal para que ela renderize com dados atualizados?

Ficamos sem entender, mas, se tiver como criar um exemplo minimo de código e explicar o que precisa fazer acho que podemos ajudar, mas, assim é tipo “eu não entendi nada”

Quando crio um projeto sem usar Expo, uma classe que estende de Component, tem a função render() e se crio outra classe que extende de Component, para depois incluir na classe principal apenas usando <OutraClasse/>, consigo chamar uma função assíncrona chamada no começo desta outra classe, no método construtor, passando como parâmetro para a função async o this e lá dentro da função async, quando ela puxar dados de um site, ela vai usar o this, mas chamada de classe, então classe.setState({dados: retorno do fetch}).
Tudo isto faz renderizar a classe **<OutraClasse>** dentro da classe principal.
No Expo, temos uma função principal exportada e carregada no carregamento do App, chamada de App(), mas se chamo ela de dentro da função async, nada acontece.

Parece que você está desenvolvendo em React Native?

Se for pode postar essas duas classes e o problema encontrado com a tela de erro?

O problema que enfrento não é um erro em tempo de execução, mas a dúvida sobre como chamar a função principal para ela renderizar a tela com novos dados trazidos de uma função assíncrona, tendo em vista que ao usar o nome dela, App(), nada acontece diferente do setState que usamos em desenvolvimento sem Expo.

Se você não exemplificar e mostrar algo não tem como ajudar …

Quer fazer talvez algo que não funcione, eu acho que funciona

Na linha 33, quando App(), nada acontece e sem usar Expo, bastaria, fazer classe.setState({chave: valor}), logo renderizava novamente:

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
let nome = ''
esperarsegundos()

export default function App() {
  return (
    <View style={styles.container}>
      <Text style={styles.green}>Verde</Text>
      <Text style={styles.bigblue}>Azul</Text>
      <Text style={[styles.bigblue, styles.green]}>Azul, depois verde</Text>
      <Text style={[styles.green, styles.bigblue]}>Verde, depois azul</Text>
      <Text>{nome ? nome : ''}</Text>
    </View>
  );
}

async function esperarsegundos(){
  setTimeout(() => {
    styles.green = {
      color: 'black',
      fontSize: 100
    }   
    styles.green = {
      color: 'black'
    } 
    nome = 'umapessoaqualquer'
    styles.green = {
      color: 'green',
      fontSize: 30
    }
    console.log(styles.green, nome)
    App()
  }, 3000)
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  bigblue: {
    color: 'blue',
    fontWeight: 'bold',
    fontSize: 50
  },
  green: {
    color: 'green',
    fontSize: 30
  }
});

Isso que você não funciona, chamar o componente no meio de uma função! Simples a resposta.

E onde eu deveria chamá-la pra ocorrer uma nova renderização da tela principal?

Dentro da funão ela que precisa ter estado …:

function App() {

Exemplifique. Não entendi nada.

Dentro da function App ter as funções, tem estados de variáveis quando você atualizar uma lista a função esta dentro da App.

Exemplo:

export default function App() {

  const [message, setMessage] = useState('');
  const [list, setList] = useState([]);
  const inputMessage = useRef();

  function handlerMessageChange(event) {
    const { value } = event.target;
    setMessage(value);
  }

  function handlerButtonSend() {
    socket.emit('chat message', message);
    setMessage(''); 
    handleInputMessageFocus();   
  }

ReferenceError: Can’t find variable: useState

  • App.js:7:41 in App
  • node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-dev.js:9473:27 in renderWithHooks
  • node_modules/react-native/Libraries/Renderer/oss/ReactNativeRenderer-dev.js:11994:6 in mountIndeterminateComponent
  • … 18 more stack frames from framework internals

Eu modifiquei para o código abaixo e colocando um console.log dentro da função App(), percebi que ela é chamada novamente, entretanto não atualiza o return com a variável nome.

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
let nome = 'vazio'

let chamouFuncao = false
export default function App() {
  console.log('Dentro da função App e a variável nome é '+nome)
  if(!chamouFuncao){
    esperarsegundos()
  }
  chamouFuncao = true
  /*
  const [message, setMessage] = useState('');
  const [list, setList] = useState([]);
  const inputMessage = useRef();

  function handlerMessageChange(event) {
    const { value } = event.target;
    setMessage(value);
  }

  function handlerButtonSend() {
    socket.emit('chat message', message);
    setMessage(''); 
    handleInputMessageFocus();   
  }
*/
  async function esperarsegundos(){
    let antes = Date.now()
    setTimeout(() => {
      styles.green = {
        color: 'black',
        fontSize: 100
      }   
      styles.green = {
        color: 'black'
      } 
      nome = 'umapessoaqualquer'
      styles.green = {
        color: 'green',
        fontSize: 30
      }
      console.log(styles.green, nome)
      App()
      
    }, 3000)
    //App()
    console.log('A função async durou '+(Date.now() - antes)+ '  milissegundos.')
  }
  return (
    <View style={styles.container}>
      <Text style={styles.green}>Verde</Text>
      <Text style={styles.bigblue}>Azul</Text>
      <Text style={[styles.bigblue, styles.green]}>Azul, depois verde</Text>
      <Text style={[styles.green, styles.bigblue]}>Verde, depois azul</Text>
      <Text>{nome ? nome : 'false'}</Text>
    </View>
  );
}



const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  bigblue: {
    color: 'blue',
    fontWeight: 'bold',
    fontSize: 50
  },
  green: {
    color: 'green',
    fontSize: 30
  }
});

Deve ser a versão que está usando ! é um problema oculto difícil a gente saber

Quanto àquele erro acima, era só colocar , { useState } from ‘react’. Sei que não percebeu isso :wink: . Sinceramente, estou em um tipo diferente de raciocínio para entender este novo tipo de código por esses poucos dias que se sucederão.

Consegui da forma abaixo, mas algo intrigante é que ontem tentei o mesmo código, mas quando chegava na linha do fetch, a função não passava a mais nenhuma linha e um console.log abaixo do fetch não executava. De um dia para o outro, isso pára de acontecer. Já é a segunda vez que me acontece isso.

import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';

class Dados extends Component {
  constructor(props){
    super(props)
    this.state = {dados: <Text>Maria</Text>}
    pegarDados('http://swapi.co/api/films/2', this)
  }

  render() {
    return(
      <View>{this.state.dados}</View>
    )
  }
}

async function pegarDados(url, elementoComSetState){
  try {
    //console.log('entrou no try')
    let resposta = await fetch(url)
    let respostaJson = await resposta.json()
    let entradasResposta = Object.entries(respostaJson)
    let valoresResposta = Object.values(Response)
    let chavesResposta = Object.keys(respostaJson)
    let resultado = []
    console.log(chavesResposta)
    for(let i = 0; i < chavesResposta.length; i++){
      resultado.push(<Text>{chavesResposta[i]}</Text>)
      resultado.push(<Text>{valoresResposta[i]}</Text>)
    }
    elementoComSetState.setState({dados: resultado})
  } catch(erro) {
    //console.log(erro)
  }
}

export default function App() {
  return (
    <View style={styles.container}>
      <Dados/>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
//