我是 React Hooks 的新手,无法解决状态问题。我已经在 Stack Overflow 的其他地方读到了关于 useState/useImpact 的异步性质,似乎无论我尝试什么,包括 async/await,我都无法将 JSON 数组结果分配给我的 [data, callback] 以在我的主 App(.js( 中的简单表中呈现返回数据的元素 - 见下文。我有一个App.js
,一个Hooks.js
和一个Tradetable.js
,其中填充了元素表(后两个文件在App.js
中导入(。
应用.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
钩子.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 };
表/交易表.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
调用的数据填充并代表新状态?特别是,"查看交易"略低App.js
非常感谢任何指导!
来自useState
文档:
状态参数是初始呈现期间使用的状态。 在随后的渲染中,它被忽略。
在初始渲染App
时,tradeData
是一个空数组,因为获取尚未完成。tradeData
仅用作useState
的初始状态参数。
随后,当提取完成并且tradeData
保存获取的数据时,此更新的tradeData
值不会复制到trades
状态变量中。
您可以使用效果将加载的tradeData
复制到trades
:
useEffect(() => {
setTrades(tradeData)
}, [tradeData]);