簡體   English   中英

未處理的拒絕(TypeError):破壞非迭代實例的無效嘗試

[英]Unhandled Rejection (TypeError): Invalid attempt to destructure non-iterable instance

我正在嘗試學習地圖方法。 如果我使用此語法response.data.map(d =>可以迭代數據數組並查看結果,但是如果我使用此語法response.data.map(([label, CustomStep]) => { ,正在收到以下錯誤:

Unhandled Rejection (TypeError): Invalid attempt to destructure non-iterable instance

您能告訴我如何修復它,以便將來自己修復嗎?

在下面提供我的代碼段:

axios
.get('http://world/sports/values')
.then(response => {
    console.log("sports--->", response.data.map(d => d.customFieldValueName));
    //this.setState({ playerRanks: response.data.map(d => d.customFieldValueName) });
    // es6 map
    //Unhandled Rejection (TypeError): Invalid attempt to destructure non-iterable instance
    this.setState({
        playerRanks: response.data.map(([label, CustomStep]) => {
            label.customFieldValueName
        })
    })
})

更新1:

嘿,我在控制台中看到,數據是一個數組,里面有很多對象

 data: Array(19)
        [
            {
                "customFieldValueCode": "player1",
                "customFieldValueName": "player1",
                "isActive": "Y"
            },
            {
                "customFieldValueCode": "player 2",
                "customFieldValueName": "player 2",
                "isActive": "Y"
            }
        ]

編輯:

根據提供的數據結構,您可以修改代碼以...

axios
.get('http://world/sports/values')
.then(response => {
    this.setState({
        playerRanks: response.data.map(obj => {
            return obj.customFieldValueName
        })
    })
})

要么

    ...
    response.data.map(({customFieldValueName}) => {
        return customFieldValueName;
    })
    ...

甚至...

    ...
    response.data.map(({customFieldValueName}) => customFieldValueName)
    ...

但這是我推薦的解決方案,可以對您的數據進行類型檢查並進行適當的錯誤處理...

axios
.get('http://world/sports/values')
.catch(err=> console.log(err))
.then(({data}) => {                       // Axios always returns an Object, so I can safely 'attempt' to destructure 'data' property 
    if (data && data.length) {            // making sure 'data' does exist, it is an Array and has > 0 elements
      this.setState({
        playerRanks: data.map(obj => {    // Not destructuring here in case obj isn't actually an Object
            if (obj && obj.customFieldValueName) return customFieldValueName;
            return null;
        }).filter(elem=> elem)            // BIG-O notation: This sequence is O(2N), as in iterates over the entire Array first with .map(), then iterates over the entire Array again with .filter() to clear out 'null' values
      })
    }
})

為了防止上面返回的Array在不符合我們的斷言的情況下包含一堆null元素,可以使用Array.reduce()方法來“過濾”任何null s。

axios
.get('http://world/sports/values')
.catch(err=> console.log(err))
.then(({data}) => {                       // Axios always returns an Object, so I can safely 'attempt' to destructure 'data' property 
    if (data && data.length) {            // making sure 'data' does exist, it is an Array and has > 0 elements
      this.setState({
        playerRanks: data.reduce((acc,obj) => {    // Not destructuring here in case obj isn't actually an Object
            if (!obj || !obj.customFieldValueName) return acc; // If it doesn't meet assertions just return the existing accumulator (don't add another element .ie 'null')
            return [                        
                ...acc,                      // If it conforms to the assertions the return a new accumulator, by first spreading in all existing elements and the adding the new one (customFieldValueName)
                customFieldValueName
            ]
        },[])                      // BIG-O notation: This is O(1N) or O(N), as in it will only iterate over the Array one time and the reduce() function will filter out 'null' values at the same time
      })
    }
})

注意: 我也只是在第一個示例的末尾添加了.filter(elem=> elem) ,它與新的.reduce()功能具有相同的功能,但是在1N而不是2N操作中完成。

預先記錄的數據

這是Array.map() 方法的工作方式...

[1,2].map(element=> {
// element === 1, first iteration,
// element === 2, second iteration
})

這是數組解構的工作方式...

[one, two, ...theRest] = [1,2,3,4,5]

// one === 1 and two === 2 and theRest = [3,4,5]

對象解構的工作原理如下...

{one, three, ...theRest} = {one: 1, two: 2, three: 3, four: 4, five: 5}

// one === 1 and three === 3 and theRest === {two: 2, four: 4, five: 5}
// notice order doesn't matter here (three vs two), but you need to access valid properties from the object you're deetructuring from

因此,根據功能的結構方式,您假設response.data的數據結構為...

response.data === [ 
   [ 
     { customFieldValueName: 'any value' }, // label
     {}                                     // CustomStep (this could be any value, not necessarily an Object) 
   ],
   [ 
     { customFieldValueName: 'any value' }, // label
     'any value'                            // CustomStep
   ]
]

我希望這在概念上有所幫助,但是如果您想要一個可行的解決方案,我們將需要...

  1. response.data數據結構。 您能否提供console.log( JSON.stringify( response.data, null, 5) )
  2. 您嘗試分配給新的this.state.playerRanks數組的特定值。

PS:查看使用當前代碼進行對象分解的一種好方法是更改​​...

.then( response => {

.then( ({data}) => {

在這種情況下,您應該確定response.data是一個數組數組,因為對於response.data.map每次迭代,您提供給map的函數必須接收一個數組才能成功提取labelCustomStep值, CustomStep要用來解構function參數的語法。

假設以下示例中的dataresponse.data ,而parseData函數是您要傳遞給map的函數:

let data = [
  [{ customFieldValueName: 'field name' }, { stepData: {} }],
  [{ customFieldValueName: 'another field name' }, { stepData: {} }]
];

let parseData = ([label, CustomStep]) => console.log(label.customFieldValueName);

parseData(data[0]); // prints out 'field name'

否則,如果response.data是一個對象數組,這似乎是由於您能夠成功運行response.data.map(d => d.customFieldValueName) ,則可以將地圖更新為此(如果您只是想將customFieldValueName值從對象中拉出):

response.data.map(({ customFieldValueName }) => customFieldValueName)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM