gpt4 book ai didi

javascript - useState 不会使用 React Hooks 的 async/await 呈现 axios 调用的结果

转载 作者:行者123 更新时间:2023-12-01 00:34:42 26 4
gpt4 key购买 nike

我是 React Hooks 新手,无法修复状态问题。我在 Stack Overflow 上的其他地方读过有关 useState/useEffect 的异步性质的内容,似乎无论我尝试什么,包括 async/await,我都无法将 JSON 数组结果分配给我的 [data,callback] 来渲染返回数据的元素在我的主应用程序(.js)的一个简单表格中 - 见下文。我有一个 App.js、一个 Hooks.js 和一个 Tradetable.js,其中填充了元素表(后者两个文件被导入到 App.js 中)。

App.js

import React, { useState, Fragment } from 'react'
import AddTradeForm from './forms/AddTradeForm'
import EditTradeForm from './forms/EditTradeForm'
import TradeTable from './tables/TradeTable'
import { useFetch } from './Hooks'

const App = () => {
// get Data from API call
const URL = "http://192.168.1.1:3000/api/queryMyCommodity"; //
const tradeData = useFetch(URL, {username:'john', channel:'channel1', name: 'GOLD'}); // the result of this `axios` call inside `useFetch` (in Hooks.js below), is exactly the same as the commented `const` line below - which would work just fine for table item rendering, ie when testing with a JSON array of 3 table items.

// const tradeData = [{"class":"demoCommodity","description":"really fabulous gold","fcn":"demoCreate","id":"trade001","name":"GOLD","owner":"JOHAN.BRINKS","tradename":"GLD"},{"class":"org.example.trading.Commodity","description":"more fabulous gold","fcn":"demoCreate","id":"trade004","name":"GOLD","owner":"NED.SLIVOVITZ","tradename":"GLD"},{"class":"org.example.trading.Commodity","description":"absolutely fabulous gold","fcn":"demoCreate","id":"trade005","name":"GOLD","owner":"ED.GOLDBERG","tradename":"GLD"}]

// Setting state
const [trades, setTrades ] = useState(tradeData); // this is the line with the issue
console.log("trades in App is set to " + JSON.stringify(trades)); // `trades` is empty [] but `tradeData` has data, being evaluated later perhaps?
const initialFormState = { id: '' , name: '', tradename: '' }; // not using all fields in form fyi
const [ currentTrade, setCurrentTrade ] = useState(initialFormState)
const [ editing, setEditing ] = useState(false)

// CRUD operations
const addTrade = trade => {
trade.id = trades.length + 1
setTrades([ ...trades, trade ])
}

const deleteTrade = id => {
setEditing(false)

setTrades(trades.filter(trade => trade.id !== id))
}

const updateTrade = (id, updatedTrade) => {
setEditing(false)

setTrades(trades.map(trade => (trade.id === id ? updatedTrade : trade)))
}

const editRow = trade => {
setEditing(true)

setCurrentTrade({ id: trade.id, name: trade.name, tradename: trade.tradename })
}

return (
<div className="container">
<h1>Trading App CRUD-style</h1>
<div className="flex-row">
<div className="flex-large">
{editing ? (
<Fragment>
<h2>Edit trade</h2>
<EditTradeForm
editing={editing}
setEditing={setEditing}
currentTrade={currentTrade}
updateTrade={updateTrade}
/>
</Fragment>
) : (
<Fragment>
<h2>Add trade</h2>
<AddTradeForm addTrade={addTrade} />
</Fragment>
)}
</div>
<div className="flex-large">
<h2>View trades</h2>
<TradeTable trades={trades} editRow={editRow} deleteTrade={deleteTrade} />
</div>
</div>
</div>
)
}

export default App

Hooks.js

import React, { useState, useEffect } from "react";
import axios from 'axios'

const useFetch = (httpurl, options) => {
const [mydata, setData] = useState([]);

useEffect(() => {
async function fetchData() {
const response = await axios({
method: 'POST',
url : httpurl,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
data: options
});
setData(response.data); // what comes back is set to a JS variable called 'data'
}
fetchData();
}, [httpurl]);

return mydata;
};

export { useFetch };

表格/TradeTable.js

import React from 'react'

// this is where the App will process `trades` and process/render to view in a table, then take a CRUD action etc.

const TradeTable = props => (
<table>
<thead>
<tr>
<th>Name</th>
<th>Tradename</th>
<th>Trade Actions</th>
</tr>
</thead>
<tbody>
{props.trades.length > 0 ? (
props.trades.map(trade => (
<tr key={trade.id}>
<td>{trade.name}</td>
<td>{trade.tradename}</td>
<td>
<button
onClick={() => {
props.editRow(trade)
}}
className="button muted-button"
>
Edit
</button>
<button
onClick={() => props.deleteTrade(trade.id)}
className="button muted-button"
>
Delete
</button>
</td>
</tr>
))
) : (
<tr>
<td colSpan={3}>No trades</td>
</tr>
)}

那么 - 如何确保 trades[] 由来自 axios 调用的数据填充并代表新的 State ?特别是,“查看交易”进一步向下 App.js

提前非常感谢您的指导!

最佳答案

来自 useState 文档:

The initialState argument is the state used during the initial render. In subsequent renders, it is disregarded.

App的初始渲染期间,tradeData是一个空数组,因为提取尚未完成。 tradeData 仅用作 useState 的初始状态参数。

随后,当获取完成并且 tradeData 保存获取的数据时,tradeData 的更新值不会复制到 trades 状态变量中。

您可以使用效果将加载的 tradeData 复制到 trades:

useEffect(() => {
setTrades(tradeData)
}, [tradeData]);

关于javascript - useState 不会使用 React Hooks 的 async/await 呈现 axios 调用的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58227485/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com