At first, I create an object array address using useState.
In useEffect, I want to update address after I get the response from API.
The ultimate value of address should be
[
{ id: "unit", label: "Unit", value: "Unit 1" },
{ id: "floor", label: "Floor", value: "Floor 1" },
{ id: "block", label: "Block", value: "Block 1" }
]
How can I do it?
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
Assuming all items in address have a matching value in responseData you could use:
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] }))
));
}, []);
The code above loops through the address array and maps each item to one with an updated value found in responseData.en.
The reason I'm using a callback is because you should use a callback if the new state depends on the previous state. Since you only want to update a single property of an item (and not completely replace the state) the new state depends on the old state, thus you use a callback.
You can update in the following way:
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
}
]);
}, []);
For your reference: https://codesandbox.io/s/hopeful-silence-gs1yq?file=/src/App.js:425-1015
try like this, if en available, it will take en, else whatever first lang available
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??
}, []);