reactjs 状态设置器未设置完成状态next js

wvt8vs2t  于 2022-12-22  发布在  React
关注(0)|答案(1)|浏览(127)

我不知道这是状态设置的问题,还是我的Map渲染的问题,但是,当我试图设置一个数组变量的状态时,我只得到一个元素来显示。当我打印出数组中的元素时,它显示了所有内容,但当我设置状态时,它不工作。我认为这可能是由于它是一个异步函数,因为这是代码中唯一能区分这个函数和一个类似函数的东西。我在使用效果中完成了所有的状态设置和获取,但即使这样,我也只能得到一个元素来Map。

const [documents, setDocuments] = useState([]);
    const [listDocuments, setListDocuments] = useState([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(false);
    
    const dataFetchedRef = useRef(false);
    const {currentUser} = UseAuth();
    
    const router = useRouter()

    const [averagePrice, setAveragePrice] = useState({})

    function getLoc() {
        if (currentUser) {
            return 'users/' + currentUser.uid + '/userInvestments'
        } else {
            return 'users/TestDocumentForDatabase/userInvestments'
        };
    }

    
useEffect(() => {
        if (!currentUser) {
            router.push('/login');
        } else {
            if(dataFetchedRef.current) return;
            dataFetchedRef.current = true;
            

            const setData = async() => {
                let data = []
                let avgMap = new Map()

                const loc = getLoc();
                const q = query(collection(db, loc));
                const snapshot = await getDocs(q)

                snapshot.forEach(async doc => {       
                    const obj = doc.data()
                    data.push(obj)
                    let tic = doc.data().stockTicker;
                    
                    if (avgMap.has(tic)) {
                        console.log("Has")
                        let data = avgMap.get(tic)
                        const type = doc.data().type;
                        let newShares = parseFloat(data.shares);
                        let newPrice = parseFloat(data.price);
                        const oldAmount = newShares * newPrice
                        if (type === "buy") {
                            newShares = newShares + parseFloat(doc.data().shares);
                            newPrice = (oldAmount + parseFloat(doc.data().price))/newShares;
                        } else {
                            newShares = newShares - parseFloat(doc.data().shares);
                            newPrice = (oldAmount - parseFloat(doc.data().price))/newShares;
                        }

                        const newData = {
                            price: newPrice,
                            shares: newShares,
                            stockTicker: tic,
                        }
                        avgMap.set(tic, newData)
                    } else {
                        console.log("Doesnt Have")
                        avgMap.set(tic, doc.data())
                    }
                })

                let retList = []
                avgMap.forEach(async (value, key) => {
                    const newPrice = await getStockPrice(key)
                    const currentPrice = parseFloat(newPrice.toFixed(2))
                    const pl = (parseFloat(value.shares)*(currentPrice - parseFloat(value.price))).toFixed(2)
                    const fixedPrice = (value.price).toFixed(2)
                    let insertAvg = {
                        ticker: key,
                        shares: value.shares,
                        averagePrice: fixedPrice,
                        currentPrice,
                        profitLoss: pl,
                        dividendYield: "Coming Soon"
                    }
                    retList.push(insertAvg)
                    setListDocuments([...listDocuments, insertAvg])
                    console.log(retList)

                    console.log(listDocuments)
                }) 
                
                console.log(retList)
                // setListDocuments(retList)
                console.log(listDocuments)
                setDocuments(data)
                console.log(documents)

                // data.forEach(doc => {
                    
                // })
                // (Object.keys(averageData).map(tic => {
                //     console.log("Tic" + tic)
                // }))

                setLoading(false)
            }
            setData()
            console.log(documents)
        }
    }, [listDocuments, documents])
    return (
        <div className='flex justify-center items-center flex-col gap-5'> 
             {!loading && 
                
                    <div className="container bg-white rounded px-20">
                        <div>
                        <table className="w-full flex flex-row flex-no-wrap sm:bg-white rounded-lg overflow-hidden sm:shadow-lg my-5">
                            <thead className="text-white">
                                {listDocuments?.map(doc => {
                                    return (<tr className="bg-gray-600 flex flex-col flex-nowrap sm:table-row rounded-lg sm:rounded-none mb-2 sm:mb-0">
                                        <th className="p-3 text-left">Type</th>
                                        <th className="p-3 text-left">Shares</th>
                                        <th className="p-3 text-left">Price</th>
                                        <th className="p-3 text-left">Return</th>
                                        <th className="p-3 text-left" width="110px">Actions</th>
                                    </tr>)
                                })}
                            
                            </thead>
                            <tbody className="flex-1 sm:flex-none text-black">
                                {listDocuments?.map(doc => {
                                    return (
                                        <tr className="flex flex-col flex-nowrap sm:table-row mb-2 sm:mb-0">
                                            <td className="border-grey-light border hover:bg-gray-100 p-3">John Covv</td>
                                            <td className="border-grey-light border hover:bg-gray-100 p-3 truncate">contato@johncovv.com</td>
                                            <td className="border-grey-light border hover:bg-gray-100 p-3 truncate">contato@johncovv.com</td>
                                            <td className="border-grey-light border hover:bg-gray-100 p-3 text-red-400 hover:text-red-600 hover:font-medium cursor-pointer">Delete</td>
                                        </tr>
                                    )
                                })}
                            </tbody>
                        </table>
                        </div>
                        {tableizeData()}
                    </div>



                
            }
           ..... more variations of table designs

这是功能组件的呈现方面。

{
 listDocuments?.map(doc => {
       return (<tr className="bg-gray-600 flex flex-col flex-nowrap 
       sm:table-row rounded-lg sm:rounded-none mb-2 sm:mb-0">
               ... more code to show data

我也有同样的密码,但它是

{
 documents?.map((doc) => {
     return (
          <tr key={doc.ticker}>
               <td className="px-6 py-2 text-center">
               ... more code to show data

而且效果很好,为什么呢

exdqitrt

exdqitrt1#

...
let retList = []
avgMap.forEach(async(value, key) => {
  const newPrice = await getStockPrice(key)
  const currentPrice = parseFloat(newPrice.toFixed(2))
  const pl = (parseFloat(value.shares) * (currentPrice - parseFloat(value.price))).toFixed(2)
  const fixedPrice = (value.price).toFixed(2)
  let insertAvg = {
    ticker: key,
    shares: value.shares,
    averagePrice: fixedPrice,
    currentPrice,
    profitLoss: pl,
    dividendYield: "Coming Soon"
  }
  retList.push(insertAvg)
  // Don't setter in for-loop
  // setListDocuments([...listDocuments, insertAvg])
  console.log(retList)

  console.log(listDocuments)
});
// You should set state once after for-loop
setListDocuments((prev)=> [...prev, ...retList]);

相关问题