我正在獲取帶有陣列和值的異步物件。我想獲取該陣列并將該其他值添加到隨機索引處的同一陣列中。
{
incorrect_answers: ['item1', 'item2', 'item3'],
correct_answer: 'item4'
}
// I expect this: ['item1', 'item2', 'item4', 'item3'] the index for 'item4' is random
我用 useState 很好地得到了陣列,但不知道如何在同一 useState 行中添加其他值:
const [index, setIndex] = useState(0);
const [answers, setAnswers] = useState([]);
useEffect(()=>{
(async () => {
const data = await fetch ('https://opentdb.com/api.php?amount=10&type=multiple');
const json = await data.json();
setAnswers(json.results[index].incorrect_answers);
//if I use .splice here, I get only the correct_answer in the array
answers.splice(random,0, json.results[index].correct_answer);
setAnswers(answers)
})();
}, []);
更新:
完整的專案在這里:https ://codepen.io/metsuge/pen/qBxyrMY 這個想法是當點擊下一個問題時,索引會更新以顯示陣列中的下一個物件。但是 NextQuestion() 和 if 陳述句中的索引值是 1,所以問題和答案是混合的
uj5u.com熱心網友回復:
- 您的第二個
setAnswer可能指向舊answers陣列,因為呼叫setAnswer可以異步。
const [index, setIndex] = useState(0);
const [answers, setAnswers] = useState([]);
useEffect(()=>{
(async () => {
const data = await fetch ('');
const json = await data.json();
setAnswers(json.results[index].incorrect_answers);
// answers may equal to []
answers.splice(random,0, json.results[index].correct_answer);
setAnswers(answers)
})();
}, []);
- React 將批處理你的兩個
setAnswers呼叫,并且只會呼叫 2ndsetAnswer。所以你incorrect_answers永遠不會設定為answers陣列。因此,您實際上是在拼接初始空陣列。
- 您正在改變原始資料。所以不知何故,如果你設法設定
incorrect_answersbefore insertcorrect_answer并且仍然使用answers.splice,那么原始資料將發生變化。因此,在您對原始資料集進行變異后,您可以呼叫setAnswers(answers)帶有變異資料的 。當 react 將舊值與提供的新值進行比較時setAnswers,發現兩者相等。所以 React 會忽略狀態更新。
如何解決問題
const [index, setIndex] = useState(0);
const [answers, setAnswers] = useState([]);
useEffect(()=>{
(async () => {
const data = await fetch ('');
const json = await data.json();
const data = json.results[index].incorrect_answers;
data.splice(random,0, json.results[index].correct_answer);
setAnswers(data);
})();
}, []);
參考
- https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
- https://reactjs.org/docs/react-component.html#state
更新
我已經更新了你的QuizeComponent
function QuizComponent() {
const [APIData, setAPI] = useState({});
const [question, setQuestion] = useState("");
const [index, setIndex] = useState(0);
const [answers, setAnswers] = useState([]);
const [objectsLength, setObjectsLength] = useState(0);
useEffect(() => {
(async () => {
const data = await fetch(
"https://opentdb.com/api.php?amount=10&type=multiple"
);
const json = await data.json();
setAPI(json.results);
setObjectsLength(json.results.length);
})();
}, [])
useEffect(() => {
if (APIData[index]) {
const random = Math.floor(Math.random() * 5);
const data = APIData[index];
const cpy = [...data.incorrect_answers];
cpy.splice(random, 0, APIData[index].correct_answer);
setAnswers(cpy);
setQuestion(data.question);
}
}, [index, APIData])
const nextQuestion = function () {
if (index !== objectsLength.length - 1) {
setIndex(index 1);
setQuestion(APIData[index].question);
setAnswers(APIData[index].incorrect_answers);
} else {
console.log("This is the last question.");
}
};
return (
<div className="QuizComponent">
<h1>QUIZ COMPONENT</h1>
<div>
<Question question={question} APIData={APIData} index={index} />
</div>
<div>
<button onClick={() => nextQuestion(index)}>Next question</button>
</div>
<div id="main-answers-container">
{answers.map(function (item, i) {
return <Answer key={i} answer={item} index={index} />;
})}
</div>
</div>
);
}
uj5u.com熱心網友回復:
在我的控制臺中,您的代碼運行良好。我認為問題一定是您正在對狀態變數進行操作。您可以嘗試對陣列進行深拷貝,然后使用 splice,然后使用 setState。像這樣的東西:
const deepCopy = [...answers]
deepCopy.splice(random,0, json.results[index].correct_answer);
setAnswers(deepCopy)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/485826.html
標籤:javascript 反应 异步等待 使用状态 数组拼接
