Как указывал Jayce444, setActive({i:false});
в рендере вызовет у вас проблемы из-за бесконечного l oop.
Как бы то ни было, вы неправильно набираете setActive
. Вызов setActive({i:!active.i})
полностью перезапишет объект состояния в виде одной пары ключ / значение. Пример:
Допустим, вы начинаете с
active = {1: true, 2: false}
// then you call
setActive({2:!active.2}) // now active looks like {2:!false} = {2: true}
// then you call
setActive({1:!active.1}) // now active looks like {1:!undefined} = {1: true}
// in this case you just happen to be getting lucky because
// all <IonRadio ... checked={active.i} ../> (other than your current set i)
// are evaluating to checked={undefined} which is the same as unchecked
. Вам не хватает скопировать существующее состояние перед обновлением конкретного ключа. Таким образом, собрать все вместе здесь возможно ( CodeSandbox здесь )
const [active, setActive] = useState({});
const [oneOnly, setOneOnly] = useState("");
return (
<div className="App">
<h3>If you want to have multiple selections</h3>
{Object.values(equipment).map((item, i) => (
<label>
<input
key={item+"multi"}
type="radio"
value={item+"multi"}
checked={active[item] || false}
onClick={e => {
setActive({ ...active, [item]: !active[item] });
}}
/>
{i}) {item}
<br />
</label>
))}
<h3>... Or just one</h3>
{Object.values(equipment).map((item, i) => (
<label>
<input
key={item + "single"}
type="radio"
value={item + "single"}
checked={oneOnly === item}
onClick={e => {
setOneOnly(item);
}}
/>
{i}) {item}
<br />
</label>
))}
</div>
)