![](/img/trans.png)
[英]how can I destructure from an array of objects when data is coming from database dynamically?
[英]How can I destructure a state array of objects in this react component to use individual field data
獲取后,我在組件的 state 的數組中有 96 個對象。 除了年份和某些情況下的月份之外,它們都是唯一的對象。 年份不能靜態設置,因為它顯然會在某個時候發生變化。 月份將從Integer
轉換為String
。 我試圖 map 它,但我得到一個錯誤,說cannot read property map of undefined
。 但是,如果我console.log
數據,我將得到包含 96 個對象的數組。 當我嘗試解構它時,我得到一個錯誤Invalid attempt to destructure non-iterable instance
。 我的主要目標是獲取年份並將其作為模板文字傳遞給headerName
,以便它作為下面所有數據的分組列加載。 並取月 integer 並將其轉換為該月的字符串我的該組件的代碼如下。
import React, { Component } from "react";
import { AgGridReact } from "ag-grid-react";
class ColumnGroups extends Component {
constructor(props) {
super(props);
this.state = {
columnDefs: [
{
headerName: "Year",
field: "year",
children: [
{
headerName: "Month",
field: "month",
width: 150,
children: [
{
headerName: "Sold",
field: "sales",
width: 150
},
{
headerName: "Return",
field: "returns",
width: 150
},
{
headerName: "RMA%",
field: "rma",
width: 150
}
]
}
],
defaultColDef: {
editable: false,
sortable: true,
resizable: true,
filter: true
},
rowSelection: "multiple",
rowGroupPanelShow: "always",
pivotPanelShow: "always",
paginationPageSize: 10,
paginationNumberFormatter: function(params) {
return "[" + params.value.toLocaleString() + "]";
},
rowData: []
}
],
}
}
onGridReady = params => {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
const httpRequest = new XMLHttpRequest();
const updateData = data => {
this.setState({ rowData: data });
params.api.paginationGoToPage(4);
};
httpRequest.open(
"GET",
"http://localhost:5000/api/salessummary"
);
httpRequest.send();
httpRequest.onreadystatechange = () => {
if (httpRequest.readyState === 4 && httpRequest.status === 200) {
updateData(JSON.parse(httpRequest.responseText));
}
};
};
onPageSizeChanged(newPageSize) {
var value = document.getElementById("page-size").value;
this.gridApi.paginationSetPageSize(Number(value));
}
render() {
{console.log(this.state.rowData)}
return (
<div>
<div>
<div
className="ag-theme-balham"
style={{
height: '500px',
width: '100%' }}
>
<div className="test-header">
Page Size:
<select onChange={this.onPageSizeChanged.bind(this)} id="page-size">
<option value="10" selected="">
10
</option>
<option value="100">100</option>
<option value="500">500</option>
<option value="1000">1000</option>
</select>
</div>
<AgGridReact
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
autoGroupColumnDef={this.state.autoGroupColumnDef}
defaultColDef={this.state.defaultColDef}
suppressRowClickSelection={true}
groupSelectsChildren={true}
debug={true}
rowSelection={this.state.rowSelection}
rowGroupPanelShow={this.state.rowGroupPanelShow}
pivotPanelShow={this.state.pivotPanelShow}
enableRangeSelection={true}
pagination={true}
paginationPageSize={this.state.paginationPageSize}
paginationNumberFormatter={this.state.paginationNumberFormatter}
onGridReady={this.onGridReady}
>
</AgGridReact>
</div>
</div>
</div>
)
}
}
export default ColumnGroups;
這是返回的部分無法讀取未定義的屬性“地圖”
<div>
{
this.state.rowData.map(data => <div>{data.year}</div> )
}
</div>
數據如下
{
"year": 2019,
"month": 4,
"productStyle": "zzzzz",
"sales": 1,
"returns": 0,
"rma": 0
},
每一年都是一樣的。 映射返回 96 年,其中 95 年我不需要。 它會改變我希望這對現場年來說是動態的。 而且我需要訪問月份,這樣我就可以將integer
更改為四月等的string
3。
沒有內置的 JS 方法可以將月份數字格式化為您可以自己構建的字符串:
numToMonth(n){
switch(n){
case 1:
return 'Jan'
//... all months
default:
return 'Dec'
}
}
您需要在 map 之前進行驗證。 要更加徹底地檢查它是否存在並且它是一個數組:
render(){
if(this.state.rowData && Array.isArray(this.state.rowData)){
var items = this.state.rowData
}
return(
<div>
{items && items.map(item => <div>{item.Year}</div> )}
</div>
)
}
}
如果您需要基於當前年份的一項,請使用查找:
render(){
if(this.state.rowData && Array.isArray(this.state.rowData)){
var item = this.state.rowData.find(data => data.year === new Date().getFullYear )
}
return(
<div>
{item && `${item.year} - ${this.numToMonth(item.month)}` }
</div>
)
}
如果您需要基於當前年份過濾器的許多項目:
render(){
if(this.state.rowData && Array.isArray(this.state.rowData)){
var items = this.state.rowData.filter(data => data.year === new Date().getFullYear )
}
return(
<div>
{item && items.map(items=> <div>{item.year} - {this.numToMonth(item.month)} </div>})
</div>
)
}
如果所有年份都相同,並且您需要一堆月份數字作為字符串:
render(){
if(this.state.rowData && Array.isArray(this.state.rowData)){
var items = this.state.rowData
}
return(
<div>
{items && items[0].year}
{items && items.map(item => <div>{this.numToMonth(item.month)}</div> )}
</div>
)
}
}
最后一個示例的可運行片段:
class SomeComponent extends React.Component { state={ rowData:[ {year:1988,month:1}, {year:1988,month:3}, {year:1988,month:2}, {year:1988,month:1}, ] } numToMonth(n){ switch(n){ case 1: return 'Jan' case 2: return 'Feb' case 3: return 'March' //... all months default: return 'Dec' } } render(){ if(this.state.rowData && Array.isArray(this.state.rowData)){ var items = this.state.rowData } return( <div> {items && items[0].year} {items && items.map(item => <div>{this.numToMonth(item.month)}</div> )} </div> ) } } ReactDOM.render( <SomeComponent />, document.getElementById("react") );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="react"></div>
你可以把當年的你的state,像這樣。
state = {
...
currentYear: new Date().getFullYear();
}
然后你可以通過this.state.currentYear
過濾你的數據。
var data = this.state.rowData.find((x)=>{return x.year === this.state.currentYear})
看來rowData
需要是 AgGridReact 的AgGridReact
,因此為AgGridReact
的rowData
屬性寫入rowData={[data]}
。
編輯
如果您要根據年份過濾表中的數據(假設您想查看上一年的數據)添加onChange
function changeYear
將設置 state 並更改年份。 見下文。
changeYear = (year) =>{
this.setState({
currentYear: year
})
}
當 state 更新時,數據將被重新過濾並僅反映新選擇的年份的數據。
至於月份,你可以像這樣把數字變成一個字符串。
formatMonth = (x) =>{
var months = ['January', 'February', 'March', ..., 'December']
return months[x-1]
}
您尚未在 state 變量中初始化 rowData。 我看到您已經在構造函數的 columnDefs 的子項中定義了 rowData。 這里發生了兩件事。
因此,this.state.rowData 在初始化之前是未定義的,並且組件正在嘗試 map 超過未定義。 這就是為什么您收到錯誤Cannot read property 'map' of undefined 的原因。
this.state={... rowData:[]...}
。rowData={this.state.rowData}
的 prop 更改為rowData={Array.isArray(this.state.rowData)? this.state.rowData: []}
rowData={Array.isArray(this.state.rowData)? this.state.rowData: []}
我看到你在這個問題上問了很多事情。 這是其中的一部分。 更詳細地解釋您想要什么,或者可以將其划分為子問題。 然后很容易回答他們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.