使用JSX在React State上使用异步函数中的数据



我对React和JS有点陌生,在State上使用从ASYNC返回的数据,然后将其作为JSX传递时遇到问题。这是我的代码:

(附言:当我从内部功能控制台日志时,我从数据库接收到数据,它工作正常,但我似乎找不到在外部使用它的方法(

import {useState, useEffect} from 'react';
import {supabase} from '../db/supabase'
import styled from 'styled-components';
//CSS
const Container = styled.div`
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;`
const RandomQuote = styled.h1`
width: 75%;
font-size: 3.65em;
color: #333;`
export default function App() {
const [quote, setQuote] = useState();
useEffect(() => {
getQuotes().then().catch();
});
async function getQuotes() {
const {data, error} = await supabase
.from('quotes_en')
.select('quote')
const getRandomQuote = await data[Math.floor(Math.random() * data.length)];
if (error) console.table(error)
setQuote(getRandomQuote);
};
return (
<Container>
<RandomQuote>{quote}</RandomQuote>
</Container>
);
}

因此random_quote正在返回:带有console.log[Object]的Object quote: "Our life will pass like the traces of a cloud, it will be scattered like mist that is chased by the rays of the sun. For our time is the passing of a shadow. Our lives will run like sparks through the stubble." __proto__: Object

返回数据时:Array(4) 0: {quote: "Sometimes it takes sadness to know happiness, nois…ppreciate silence, and absence to value presence."} 1: {quote: "If there is no enemy within, the enemy outside can make us no harm."} 2: {quote: "Our life will pass like the traces of a cloud, it …r lives will run like sparks through the stubble."} 3: {quote: "Little by little, day by day, what is meant for you will find its way"} length: 4 __proto__: Array(0)[带对象数组]

所以,有人可以先解释这个问题,这样我就可以学习了,然后分享更新后的代码片段会更好。

您所需要的一切-它只是在getQuotes内部从服务器获取后的setQuote。并在钩子useEffect中使用此函数进行第一次渲染。

像这样:

const [quote, setQuote] = useState();
const getQuotes = async() => {
const {data, error} = await supabase
.from('quotes_en')
.select('quote')
const getRandomQuote = await data[Math.floor(Math.random() * data.length)];
if (error) console.table(error)
setQuote(getRandomQuote); //Here quote goes to state
};
useEffect(() => {
getQuotes().then().catch() //nasty hack for IDE
}, []);

您可能已经解决了这个问题,但我想我会为将来可能阅读到这篇文章的其他人发布。以下是您希望在useEffect中使用异步函数的方式。

export default function App() {
// set initial state to an empty array. Since arrays are immutable
const [quotes, setQuotes] = useState([]);

// your function named 'getQuotes' should return presumably all the quotes
async function getQuotes() {
const {data, error} = await supabase
// return some array of data
return data ? data : error
};
useEffect(() => {
getQuotes()
// spread the array into the state object. 
.then(response => setQuotes([...response]))
.catch(err => err);
// quotes in dependency array to only run effect when quotes changes 
}, [quotes]);

// whatever logic you use for getting a single quote from `quotes` 
const quote = quotes.from(...).select(...)
return (
<Container>
<RandomQuote>{quotes}</RandomQuote>
</Container>
);
}

为什么我们在使用useEffect 时使用这种更新状态的方式

记住数组是不可变的,所以这就是更新quotes数组内容的方式。如果设置为类似setQuotes(响应(的值,则将触发无限重渲染。详见下文。

所以,如果你这样做:

useEffect(() => {
getQuotes().then(response => setQuotes(response)).catch(err => err)
}, [quotes])

像这样,你没有将响应扩展到默认的初始数组中,而是为一个全新的数组创建设置引号,这会导致状态对象更新,从而重新渲染组件,从而再次触发useEffect。现在你有一个无限循环。

最新更新