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

16 respostas
mobileandroid
LeandroCGMS

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?

16 Respostas

Dragoon

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”

LeandroCGMS

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.

Dragoon

Parece que você está desenvolvendo em React Native?

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

LeandroCGMS

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.

Dragoon

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

LeandroCGMS

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

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

LeandroCGMS

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

Dragoon

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

function App() {
LeandroCGMS

Exemplifique. Não entendi nada.

Dragoon

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();   
  }
LeandroCGMS

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
LeandroCGMS

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

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

LeandroCGMS

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.

LeandroCGMS

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',
  },
});
Criado 15 de outubro de 2019
Ultima resposta 23 de out. de 2019
Respostas 16
Participantes 2