我正在嘗試創建一個測驗以根據選定的復選框回傳資料,我發現這樣做的最佳選擇是創建一個包含每個選定專案的索引的陣列,但是當我嘗試渲染頁面時,我收到了太多 re 的錯誤-渲染。
我有一個帶有一些問題和答案的 JSON,我正在嘗試檢索所有選定答案的串列索引,然后與我的 JSON 進行比較以回傳正確答案。
import "./questions.scss";
import React, { useState, useEffect, useRef } from "react";
import { HashLink as Link } from "react-router-hash-link";
export default function Questions({ data }) {
const [error, setError] = useState("");
const radiosWrapper = useRef();
const [updateCheckedState, setUpdateCheckedState] = useState([]);
const [temperament, SetTemperament] = useState("");
console.log(updateCheckedState);
useEffect(() => {
radiosWrapper.current.querySelectorAll("input:checked").forEach((el) => (el.checked = false));
}, [data]);
const changeHandler = (position) => {
if (!updateCheckedState.includes(position)) {
setUpdateCheckedState((arr) => [...arr, position]);
} else if (updateCheckedState.includes(position)) {
const index = updateCheckedState.indexOf(position);
setUpdateCheckedState(updateCheckedState.splice(index, 1));
}
const sanguine = data.sanguine.filter((e) => updateCheckedState.includes(e));
const choleric = data.choleric.filter((e) => updateCheckedState.includes(e));
const melancholic = data.melancholic.filter((e) => updateCheckedState.includes(e));
const phlegmatic = data.phlegmatic.filter((e) => updateCheckedState.includes(e));
const result = Math.max(sanguine.length, choleric.length, melancholic.length, phlegmatic.length);
switch (result) {
case sanguine.length:
SetTemperament("/sanguine");
break;
case choleric.length:
SetTemperament("/choleric");
break;
case melancholic.length:
SetTemperament("/melancholic");
break;
case phlegmatic.length:
SetTemperament("/phlegmatic");
break;
default:
}
if (error) {
setError("");
}
};
return (
<div className="card">
<div className="card-content">
<div className="content">
<h2 className="mb-5">{data.question}</h2>
<div className="control" ref={radiosWrapper}>
{data.choices.answer.map((choice, i) => (
<label className="radio has-background-light" key={i}>
<input type="checkbox" name="answer" value={choice} onChange={changeHandler(i)} />
{choice}
</label>
))}
</div>
{error && <div className="has-text-danger">{error}</div>}
<Link className="link" to={temperament}>
Resultado
</Link>
</div>
</div>
</div>
);
}
uj5u.com熱心網友回復:
問題出在以下行:
<input type="checkbox" name="answer" value={choice} onChange={changeHandler(i)} />
您正在呼叫該函式,而不是應該傳入一個函式,如下所示。
<input type="checkbox" name="answer" value={choice} onChange={() => changeHandler(i)} />
uj5u.com熱心網友回復:
正如 Som Shekhar Mukherjee 指出的那樣,重新渲染錯誤是由您changeHandler在渲染期間呼叫的事實引起的,因為它沒有包含在函式中。
不過,您的代碼可以簡化一大堆,注意temperament是 和 的純粹派生checked,data即 . 的主要候選者useMemo。
此外,最好使用checked復選框的道具,這樣您的狀態就永遠不會與瀏覽器顯示的內容不同步:
import "./questions.scss";
import React, { useState, useEffect } from "react";
import { HashLink as Link } from "react-router-hash-link";
function computeTemperament(data, checked) {
const temperamentCounts = {};
// Count the number of times each temperament is checked
["sanguine", "phlegmatic", "melancholic", "choleric"].forEach((temperament) => {
temperamentCounts[temperament] = data[temperament].filter(e => checked.includes(e)).length;
});
// Find the temperament with the highest count
return Object.keys(temperamentCounts).reduce((a, b) =>
temperamentCounts[a] > temperamentCounts[b] ? a : b
);
}
export default function Questions({ data }) {
const [checked, setChecked] = useState([]);
useEffect(() => {
setChecked([]);
}, [data]);
const changeHandler = React.useCallback((position) => {
if (!checked.includes(position)) {
setChecked((checked) => [...checked, position]);
} else {
setChecked((checked) => checked.filter((item) => item !== position));
}
}, []);
const temperament = React.useMemo(() => computeTemperament(data, checked), [data, checked]);
return (
<div className="card">
<div className="card-content">
<div className="content">
<h2 className="mb-5">{data.question}</h2>
<div className="control">
{data.choices.answer.map((choice, i) => (
<label className="radio has-background-light" key={i}>
<input
type="checkbox"
name="answer"
value={choice}
checked={checked.includes(i)}
onChange={() => changeHandler(i)}
/>
{choice}
</label>
))}
</div>
<Link className="link" to={temperament}>
Resultado
</Link>
</div>
</div>
</div>
);
}
uj5u.com熱心網友回復:
我認為是因為你的第二個引數useEffect和資料變化很大,每次呼叫useEffect和導致太多的重新渲染;嘗試檢查您的資料或將其從第二個引數中洗掉以查看它是否有效;
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/463382.html
標籤:javascript 数组 反应
