Я пытаюсь получить список компонентов, каждый из которых принимает пользовательский ввод и имеет отдельное состояние. Затем я хочу иметь возможность фильтровать этот список и получать компоненты, для которых, например, «переключатель» является истинным. Я пробовал много вещей, но, похоже, я не могу понять, как это сделать. Наконец я сделал это:
Мой родительский компонент
export const Parking = () => {
const [position, setPosition] = useState([false,false,false])
const onBayClick = (index) => {
position[index-1] === false? setPosition([...position.slice(0, index) , true, ...position.slice(index + 1)]):setPosition([...position, false])
}
const myBays = []
for (let i = 1; i < 4; i++) {
myBays.push(<BayForm key = {i} child = {i} state = {position[i]} onClick = {onBayClick}/>)
}
const [filteredBays, setFilteredBays] = useState(myBays)
const filterBays = () => {
setFilteredBays(myBays.filter(bay => {
return bay.position === false
}))
}
return (
<>
{myBays}
</>
)
}
Мой дочерний компонент. Я публикую только соответствующие фрагменты, поскольку они слишком длинные.
const handleClick = () => {
onClick(index)
}
<FormGroup>
<FormControlLabel control = {<Switch checked = {state} onChange = {handleClick} color = 'warning'/>} label = "Switch" />
</FormGroup>
Но когда я пытаюсь щелкнуть переключателем, я получаю следующую ошибку:
«Предупреждение: компонент меняет неконтролируемый вход на управляемый. Вероятно, это вызвано изменением значения с неопределенного на определенное значение, чего не должно происходить. Решите, использовать ли контролируемый или неконтролируемый входной элемент на протяжении всего срока службы компонента. Дополнительная информация: https://reactjs.org/link/control-comComponents%s"
Каков правильный способ сделать это? Я получаю ошибки, что бы я ни пробовал.
Что ж, я подозреваю, что вы действительно передаете неопределенное значение от Parking
до Switch
прямо здесь:
for (let i = 1; i < 4; i++) {
myBays.push(<BayForm key = {i} child = {i} state = {position[i]} onClick = {onBayClick}/>)
}
Ваш заполненный массив position[i]
имеет 3 значения, следовательно, действительными индексами являются 0, 1 и 2.
Итак, установите:
for (let i = 0; i < position.length; i++)
Если вам нужно отобразить этот индекс в вашем BayForm
, просто добавьте к нему 1
.
Также посмотрите проблему здесь:
const onBayClick = (index) => {
position[index-1] === false
? setPosition([...position.slice(0, index) , true, ...position.slice(index + 1)])
: setPosition([...position, false])
}
Эта строка setPosition([...position, false])
означает получение существующего массива, копирование его и объединение с false, что приводит к тому, что массив каждый раз увеличивается.
Для неизменяемого изменения одного значения в массиве я предлагаю использовать функцию карты:
const onBayClick = (bayIndex) => {
setPosition(previousPositions => previousPositions.map((it, index) => { // iterating through the array
if (index === bayIndex) { // if the clicked index matches this one we iterate
return !it // just set it's opposite value
}
return it // otherwise keep it as it is
}))
}
Спасибо. Я обнаружил ошибку с индексами, но тогда переключатель вообще не двигался. Теперь я вижу, что вообще не менял значение, а просто добавлял еще одно.