An asynchronous function returns a Promise
, then when using renderItens()
you will be rendering this Promise
(Object) and not its result (JSX), since it has not yet been solved. See What are javascript (promises)? for more details.
See the difference:
const funcaoAssincrona = async () => "Retorno da função assíncrona";
const funcaoSincrona = () => "Retorno da função síncrona";
console.log(`Função assíncrona não resolvida: ${funcaoAssincrona()}`);
console.log(`Função síncrona: ${funcaoSincrona()}`);
Getting the right result with async/await
See that when trying to display the content of the call funcaoAssincrona()
, is displayed [object Promise]
, so React Native launched the error that it is not possible to render an object in a JSX chunk. If you try to display it within a tag <Text>
, could, but would be shown the same as in console.log()
above.
To get the right result, you would need to make use of the await
. The above example would produce the correct effect in this way:
const funcaoAssincrona = async () => "Retorno da função assíncrona";
const funcaoSincrona = () => "Retorno da função síncrona";
const exibeRetornoAssincrono = async () => console.log(`Função assíncrona resolvida: ${await funcaoAssincrona()}`);
const exibeRetornoSincrono = () => console.log(`Função síncrona: ${funcaoSincrona()}`);
exibeRetornoAssincrono();
exibeRetornoSincrono()
Note that I needed to make use of the await
to display the result correctly. Read How ES7 async/await works? to better understand about it.
Rendering an asynchronous content
When there is something asynchronous in a component that will be displayed on the screen it is common to make use of charging states (loading) for the user to understand what is happening, since you need to render something even while it did not obtain the Promise
was not resolved.
Then your component could be made as follows (with Hooks, see What is React Hooks?):
function Cart() {
const [cartItems, setCartItems] = useState([]); // Itens do carrinho
const [isLoading, setIsLoading] = useState(true); // Começa o componente em estado de carregamento
useEffect(() => {
// Quando o componente é montado (`componentDidMount` de um componente Class),
// carregue o conteúdo do Async Storage
const loadCartItems = async () => {
const jsonItems = await AsyncStorage.getItem('CART');
if (value == null) {
setCartItems([]); // Nenhum item encontrado
} else {
setCartItems(JSON.parse(jsonItems)); // Os itens encontrados
}
setIsLoading(false); // Atualiza o estado de "loading" do componente
}
loadCartItems();
}, []);
// Esse método não é mais assíncrono
const renderItens = () => {
if (cartItems.length === 0){
return <Text>Carrinho vazio</Text>
} else {
return cartItems.map(item => <Text>Item: {item}</Text>)
}
}
if (isLoading) {
return <Text>Carregando...</Text> // Informa o usuário que está carregando
}
return <ScrollView>{renderItens()}</ScrollView>
}
If you don’t understand the use of useState
or of useEffect
, see their documentation.