我有一個這樣的json檔案:
[
{
"name": "google",
"route": "/google",
"url": "www.google.com"
},
{
"name": "bing",
"route": "/bing",
"url": "www.bing.com"
},
{
"name": "duckduckgo",
"route": "/duckduckgo",
"url": "www.duckduckgo.com"
}
]
我想獲取這個 json 檔案的每個 url 并在表中顯示獲取的狀態。我有這個有效的代碼:
// Construct an object with the JSON data
const [data, setData] = useState(jsonData)
// We need to put the fetch call inside useEffect
// otherwise the fetchData will be called over and over every time the state is updated
useEffect(() => {
let headers = new Headers()
//headers.append('Content-Type', 'application/json')
//headers.append('Accept', 'application/json')
headers.append('Origin', 'http://localhost:8080')
// Array with all the promises from each fetch
// @r contains all the info about the fetch, we are going to use the r.status later
// @i is the index of the url in the JSON file
const promises = jsonData.map((url, i) => {
return fetch(url.route, {
mode: 'no-cors',
headers: headers,
}).then((r) => ({
fetch: r,
index: i,
}))
})
Promise.all(promises)
.then((result) => {
// Iterates through each promise and replaces the status value from the JSON file
// with the status value from the fetch
const new_data = result.map((d) => {
jsonData[d.index].status = d.fetch.status
return jsonData[d.index]
})
setData(new_data)
})
.catch((error) => {
console.log('Error: ', error)
})
}, [])
現在,我更新了一點我的 json 檔案,它有點復雜:
[
{
"section": "Sonarqube",
"img": "sonarqube.png",
"urls": [
{
"name": "SonarQube",
"route": "/sonarqube",
"url": "https://sonarqube-enterprise.com"
},
{
"name": "SonarQube1",
"route": "/sonarqube",
"url": "https://sonarqube-enterprise1.com"
},
{
"name": "SonarQub2e",
"route": "/sonarqube",
"url": "https://sonarqube-enterprise2.com"
}
]
},
{
"section": "Twistlock",
"img": "twistlock.png",
"urls": [
{
"name": "Twistlock",
"route": "/twistlock",
"url": "https://twistlock.com"
}
]
}
]
我正在嘗試更改我的代碼以讀取每個部分內的urls陣列,但我無法弄清楚如何使其作業。你能幫我么。這就是我現在的位置:
const [data, setData] = useState(jsonData)
useEffect(() => {
const promises = jsonData.map((section, s) => {
return section.urls.map((url, i) => {
return fetch(url.route, {
mode: 'no-cors',
}).then((r) => ({
fetch: r,
index: i,
sectionId: s,
}))
})
})
Promise.all(promises)
.then((result) => {
const new_data = result.map((section) => {
section.map((d) => {
jsonData[d.sectionId].urls[d.index].status = d.fetch.status
jsonData[d.sectionId].urls[d.index].statusText = d.fetch.statusText
return jsonData[d.sectionId].urls[d.index]
})
})
setData(new_data)
})
.catch((error) => {
console.log('Error: ', error)
})
}, [])
我相信我快到了,但我真的不明白如何完成這項作業:O 你能幫幫我嗎
uj5u.com熱心網友回復:
您在嵌套映射中回傳陣列陣列,也不是在您的承諾中回傳jsonData.map
[
[
Promise { <pending> },
Promise { <pending> },
Promise { <pending> }
],
[ Promise { <pending> } ]
]
您需要添加.flat()到展平陣列(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat)
const promises = jsonData.map((section, s) => {
return section.urls.map((url, i) => {
return fetch(url.route, {
mode: 'no-cors',
}).then((r) => ({
fetch: r,
index: i,
sectionId: s,
}))
})
}).flat()
uj5u.com熱心網友回復:
像這樣試試。您可以先回圈外部陣列,然后執行Promises.all. 并解構你想要的屬性。
const jsonData = [ { section: "Sonarqube", img: "sonarqube.png", urls: [ { name: "SonarQube", route: "/sonarqube", url: "https://sonarqube-enterprise.com" }, { name: "SonarQube1", route: "/sonarqube", url: "https://sonarqube-enterprise1.com" }, { name: "SonarQub2e", route: "/sonarqube", url: "https://sonarqube-enterprise2.com" } ] }, { section: "Twistlock", img: "twistlock.png", urls: [ { name: "Twistlock", route: "/twistlock", url: "https://twistlock.com" } ] } ];
const App = () => {
const [data, setData] = React.useState(jsonData);
React.useEffect(() => {
const promises = jsonData.map((section, s) => {
return section.urls.map((url, i) => {
return fetch(url.route, {
mode: "no-cors"
}).then((r) => ({
fetch: r,
index: i,
sectionId: s
}));
});
});
promises.forEach((promises2) => {
Promise.all(promises2).then((result) => {
const copyJsonData = [...jsonData];
result.forEach(
({
sectionId,
index,
fetch: {
status,
statusText
}
}) => {
copyJsonData[sectionId].urls[index].status = status;
copyJsonData[sectionId].urls[index].statusText = statusText;
}
);
setData(copyJsonData);
});
});
}, []);
console.log(jsonData);
return <div></div>;
};
ReactDOM.render( < App / > , document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>
uj5u.com熱心網友回復:
我不知道您為什么要使事情復雜化,請嘗試將代碼分開,以便您可以理解和閱讀。
無論如何,這就是我將如何做到的。
const promises = [];
jsonData.map((section, s) => {
section.urls.map((url, i) => {
// create it here so the context gets in the right place.
let data = {
index: i,
sectionId: s,
}
// use push is more understandable
promises.push(fetch(url.route, {
mode: 'no-cors',
}).then((r) => ({ ...data, fetch: r })));
})
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/465320.html
標籤:javascript 反应 json 拿来
