วิธีการผลักองค์ประกอบภายใน useState array React hook? นั่นเป็นวิธีการเก่าในสถานะปฏิกิริยาหรือไม่? หรือสิ่งใหม่ ๆ ?
เช่นsetState push example ?
วิธีการผลักองค์ประกอบภายใน useState array React hook? นั่นเป็นวิธีการเก่าในสถานะปฏิกิริยาหรือไม่? หรือสิ่งใหม่ ๆ ?
เช่นsetState push example ?
คำตอบ:
เมื่อคุณใช้useState
คุณจะได้รับวิธีการอัปเดตสำหรับรายการสถานะ:
const [theArray, setTheArray] = useState(initialArray);
จากนั้นเมื่อคุณต้องการเพิ่มองค์ประกอบใหม่คุณจะใช้ฟังก์ชันนั้นและส่งผ่านอาร์เรย์ใหม่หรือฟังก์ชันที่จะสร้างอาร์เรย์ใหม่ โดยปกติอย่างหลังเนื่องจากการอัปเดตสถานะเป็นแบบอะซิงโครนัสและบางครั้งเป็นกลุ่ม:
setTheArray(oldArray => [...oldArray, newElement]);
บางครั้งคุณจะได้รับไปโดยไม่ต้องใช้รูปแบบการโทรกลับว่าถ้าคุณเพียงอัปเดตในอาร์เรย์ขนย้ายวัสดุสำหรับการจัดกิจกรรมของผู้ใช้บางอย่างที่เฉพาะเจาะจงเช่นclick
( แต่ไม่ชอบmousemove
):
setTheArray([...theArray, newElement]);
เหตุการณ์ที่เกิดขึ้นซึ่งตอบสนองเพื่อให้แน่ใจว่าการแสดงผลเป็นแดงคือ "เหตุการณ์ที่เกิดขึ้นต่อเนื่อง" ที่ระบุไว้ที่นี่
ตัวอย่างสด (ส่งการโทรกลับไปที่setTheArray
):
เพราะการปรับปรุงเท่านั้นที่จะtheArray
อยู่ในนั้นเป็นหนึ่งในclick
เหตุการณ์ (หนึ่งในกิจกรรม "ต่อเนื่อง") ผมได้รับไปกับการปรับปรุงโดยตรงในaddEntry
:
useEffect
ตัวอย่างนั้น... ?
useEffect
มีรายการอ้างอิงว่างรายการ[]
จะถูกดำเนินการในระหว่างการแสดงผลครั้งแรกเท่านั้น ดังนั้นค่าของภายในผลจะเป็นtheArray
initialArray
ในสถานการณ์ที่setTheArray([...initialArray, newElement])
ไม่สมเหตุสมผลและเมื่อtheArray
ค่าคงที่จะเท่ากับเสมอinitialValue
จึงจำเป็นต้องมีการอัปเดตการทำงาน
setTheArray(()=>theArray.concat(newElement))
จะได้ผล แต่ไม่! พารามิเตอร์ที่เรียกกลับทำให้เกิดความแตกต่างทั้งหมด
หากต้องการขยายเพิ่มเติมเล็กน้อยต่อไปนี้เป็นตัวอย่างทั่วไป เริ่มต้นด้วย:
const [theArray, setTheArray] = useState(initialArray);
const [theObject, setTheObject] = useState(initialObject);
ผลักดันองค์ประกอบที่ส่วนท้ายของอาร์เรย์
setTheArray(prevArray => [...prevArray, newValue])
พุช / อัปเดตองค์ประกอบที่ส่วนท้ายของวัตถุ
setTheObject(prevState => ({ ...prevState, currentOrNewKey: newValue}));
พุช / อัปเดตองค์ประกอบที่ส่วนท้ายของอาร์เรย์ของวัตถุ
setTheArray(prevState => [...prevState, {currentOrNewKey: newValue}]);
ผลักดันองค์ประกอบที่ส่วนท้ายของวัตถุของอาร์เรย์
let specificArrayInObject = theObject.array.slice();
specificArrayInObject.push(newValue);
const newObj = { ...theObject, [event.target.name]: specificArrayInObject };
theObject(newObj);
นี่คือตัวอย่างการทำงานบางส่วนด้วย https://codesandbox.io/s/reacthooks-push-r991u
เช่นเดียวกับที่คุณทำกับสถานะ "ปกติ" ในส่วนประกอบของคลาส React
ตัวอย่าง:
function App() {
const [state, setState] = useState([]);
return (
<div>
<p>You clicked {state.join(" and ")}</p>
//destructuring
<button onClick={() => setState([...state, "again"])}>Click me</button>
//old way
<button onClick={() => setState(state.concat("again"))}>Click me</button>
</div>
);
}
// Save search term state to React Hooks with spread operator and wrapper function
// Using .concat(), no wrapper function (not recommended)
setSearches(searches.concat(query))
// Using .concat(), wrapper function (recommended)
setSearches(searches => searches.concat(query))
// Spread operator, no wrapper function (not recommended)
setSearches([...searches, query])
// Spread operator, wrapper function (recommended)
setSearches(searches => [...searches, query])
https://medium.com/javascript-in-plain-english/how-to-add-to-an-array-in-react-state-3d08ddb2e1dc
setTheArray([...theArray, newElement]);
เป็นคำตอบที่ง่ายที่สุด แต่ต้องระวังสำหรับการกลายพันธุ์ของรายการในtheArray ใช้การโคลนไอเท็มอาร์เรย์แบบลึก
วิธีที่แนะนำมากที่สุดคือการใช้ฟังก์ชัน wrapper และตัวดำเนินการกระจายร่วมกัน ตัวอย่างเช่นหากคุณเริ่มต้นสถานะที่เรียกname
เช่นนี้
const [names, setNames] = useState([])
คุณสามารถกดไปที่อาร์เรย์นี้ได้เช่นนี้
setNames(names => [...names, newName])
หวังว่าจะช่วยได้
หากคุณต้องการผลักดันหลังจากดัชนีเฉพาะคุณสามารถทำได้ดังนี้:
const handleAddAfterIndex = index => {
setTheArray(oldItems => {
const copyItems = [...oldItems];
const finalItems = [];
for (let i = 0; i < copyItems.length; i += 1) {
if (i === index) {
finalItems.push(copyItems[i]);
finalItems.push(newItem);
} else {
finalItems.push(copyItems[i]);
}
}
return finalItems;
});
};
คุณสามารถต่อท้ายอาร์เรย์ของข้อมูลที่ส่วนท้ายของสถานะที่กำหนดเอง:
const [vehicleData, setVehicleData] = React.useState<any[]>([]);
setVehicleData(old => [...old, ...newArrayData]);
ตัวอย่างเช่นด้านล่างนี้คุณจะปรากฏตัวอย่างของ axios:
useEffect(() => {
const fetchData = async () => {
const result = await axios(
{
url: `http://localhost:4000/api/vehicle?page=${page + 1}&pageSize=10`,
method: 'get',
}
);
setVehicleData(old => [...old, ...result.data.data]);
};
fetchData();
}, [page]);
ฉันลองใช้วิธีการข้างต้นในการผลักวัตถุเข้าไปในอาร์เรย์ของวัตถุใน useState แต่มีข้อผิดพลาดต่อไปนี้เมื่อใช้TypeScript :
พิมพ์ 'TxBacklog [] | ไม่ได้กำหนด 'ต้องมีเมธอด' Symbol.iterator 'ที่ส่งคืน iterator.ts (2488)
เห็นได้ชัดว่าการตั้งค่าสำหรับ tsconfig.json นั้นถูกต้อง:
{
"compilerOptions": {
"target": "es6",
"lib": [
"dom",
"dom.iterable",
"esnext",
"es6",
],
วิธีแก้ปัญหานี้ช่วยแก้ปัญหาได้ (รหัสตัวอย่างของฉัน):
อินเตอร์เฟซ:
interface TxBacklog {
status: string,
txHash: string,
}
ตัวแปรสถานะ:
const [txBacklog, setTxBacklog] = React.useState<TxBacklog[]>();
ผลักวัตถุใหม่ลงในอาร์เรย์:
// Define new object to be added
const newTx = {
txHash: '0x368eb7269eb88ba86..',
status: 'pending'
};
// Push new object into array
(txBacklog)
? setTxBacklog(prevState => [ ...prevState!, newTx ])
: setTxBacklog([newTx]);
setTheArray(currentArray => [...currentArray, newElement])
หากข้างต้นไม่ได้ผล ส่วนใหญ่มีแนวโน้มในuseEffect(...theArray..., [])
มันเป็นสิ่งสำคัญที่จะตระหนักว่าtheArray
เป็นค่าคงที่ดังนั้นการปรับปรุงการทำงานมีความจำเป็นสำหรับค่าจากอนาคตวาทกรรม