首先,我使用useState
创建一个对象数组address
。
在useEffect
中,我想在我从API获得响应后更新address
。
address
的最终值应为
[
{ id: "unit", label: "Unit", value: "Unit 1" },
{ id: "floor", label: "Floor", value: "Floor 1" },
{ id: "block", label: "Block", value: "Block 1" }
]
我该怎么做?
App.js
import "./styles.css";
import React, { useState, useEffect } from "react";
export default function App() {
const [address, setAddress] = useState([
// the value will be updated in useEffect
{ id: "unit", label: "Unit", value: "" }, // Value should be Unit 1
{ id: "floor", label: "Floor", value: "" },// Value should be Floor 1
{ id: "block", label: "Block", value: "" } // Value should be Block 1
]);
useEffect(() => {
// let's pretent there is api GET request
let responseData = {
en: {
unit: "Unit 1",
floor: "Floor 1",
Block: "Block 1"
}
// other language address which can be ignored
};
// How to update the update of address below??
}, []);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
CodeSandbox: https://codesandbox.io/s/cranky-microservice-qjuhh?file=/src/App.js
假设address
中的所有项目在responseData
中都有一个匹配的值,您可以使用:
useEffect(() => {
// let's pretent there is api GET request
let responseData = {
en: {
unit: "Unit 1",
floor: "Floor 1",
Block: "Block 1"
}
// other language address which can be ignored
};
setAddress((address) => (
address.map((item) => ({ ...item, value: responseData.en[item.id] }))
));
}, []);
上面的代码循环遍历address
数组,并将每个元素映射到responseData.en
中具有更新值的元素。
我使用回调的原因是因为如果新状态依赖于以前的状态,你应该使用回调。由于您只想更新一个项目的单个属性(而不是完全替换状态),因此新状态依赖于旧状态,因此您使用回调。
您可以通过以下方式更新:
useEffect(() => {
// let's pretent there is api GET request
let responseData = {
en: {
unit: "Unit 1",
floor: "Floor 1",
Block: "Block 1"
}
// other language address which can be ignored
};
// How to update the update of address below??
setAddress((prevAddress) => [
{
...prevAddress[0],
value: responseData.en.unit
},
{
...prevAddress[0],
value: responseData.en.floor
},
{
...prevAddress[0],
value: responseData.en.Block
}
]);
}, []);
供参考:https://codesandbox.io/s/hopeful-silence-gs1yq?file=/src/App.js:425-1015
-
获取
responseData
中与语言分离的对象 -
map
重写状态数组,用responseData
的新值创建一个新的对象数组。
const data = [{ id: "unit", label: "Unit", value: "" },{ id: "floor", label: "Floor", value: "" },{ id: "block", label: "Block", value: "" }];
const responseData = {en: {unit: "Unit 1",floor: "Floor 1",block: "Block 1"}};
const obj = Object.values(responseData)[0];
const result = data.map(({ id, value, ...rest }) => {
return { id, value: obj[id], ...rest };
});
console.log(result);
像这样尝试,如果en可用,它将使用en,否则使用第一个可用的语言
useEffect(() => {
// let's pretent there is api GET request
let responseData = {
en: {
unit: "Unit 1",
floor: "Floor 1",
Block: "Block 1"
}
// other language address which can be ignored
};
let languagePriority = null
const availableLangs = Object.keys(responseData)
if (responseData.en) {
languagePriority = 'en'
}
if (!responseData.en && availableLangs.length) {
languagePriority = availableLangs[0]
}
if (languagePriority) {
const responseKeys =
Object.keys(responseData[languagePriority])
const addressCopy = [...address]
responseKeys.forEach(item => {
addressCopy.find(addItem => {
if (addItem.id === item) {
addItem.value = response.en[item]
}
})
})
setAddress(addressCopy)
}
// How to update the update of address below??
}, []);