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

16 respostas
mobileandroid
L

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

D

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”

L

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.

D

Parece que você está desenvolvendo em React Native?

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

L

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.

D

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

L

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

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

L

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

D

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

function App() {
L

Exemplifique. Não entendi nada.

D

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

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
L

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

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

L

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.

L

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