Контролирование нескольких инпутов в React
Есть задача: надо сделать, к примеру, 4 инпута, так что в них можно внести только целые положительные числа с 0 до 64. Я уже голову сломала над тем, как это правильно сделать, прошу о помощи.
Код:
const {useState} = React;
const App = () => {
const [value, setValue] = useState([{
id: 1,
value: 0
},
{
id: 2,
value: 0
},
{
id: 3,
value: 0
},
{
id: 4,
value: 0
}
]);
console.log(value);
function Validate(e) {
console.log(Number(e.target.name), Number(e.target.name));
if (Number(e.target.value) > 64) {
setValue([{
id: Number(e.target.name),
value: 64
}]);
} else if (Number(e.target.value) < 64) {
setValue([{
id: Number(e.target.name),
value: Number(e.target.value)
}]);
}
}
return (
<div>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div>
<input
value = {value[0].value}
name = {1}
onChange = {(e) => Validate(e)}
/>
<input
value = {value[1].value}
name = {2}
onChange = {(e) => Validate(e)}
/>
<input
value = {value[2].value}
name = {3}
onChange = {(e) => Validate(e)}
/>
<input
value = {value[3].value}
name = {4}
onChange = {(e) => Validate(e)}
/>
</div>
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('react')
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js"></script>
P.S. Пытаюсь решить через один стейт, через 4 стейта всё понятно.
Ответы (1 шт):
Автор решения: EzioMercer
→ Ссылка
Такс у вас было сразу несколько ошибок:
- Вы перепутали
e.target.valueиe.target.name - Как
nameтак иvalueнадо было приводить к числому виду, чтобы сравнивать корректно - Вы полностью перезаписывали старый стейт, массивом из всего 1-ого элемента. Я показал как надо правильно менять состояние. Очень важно сначала скопировать старые состояние чтобы его случайно не мутировать. Работаем с его копией и потому уже после всех необходимых действий вставляем изменённую копию как новый стейт
- У вас не было обработки случая, когда
value === 64
Это было не ошибкой, но писать (e) => Validate(e) лишнее нагромождение кода, т.к. если никаких специальных аргументов вы не отправляете, то все аргуметы автоматически отправятся в нужную вам ф-ию
const {useState} = React;
const App = () => {
const [values, setValues] = useState([{
id: 1,
value: 0
},
{
id: 2,
value: 0
},
{
id: 3,
value: 0
},
{
id: 4,
value: 0
}
]);
const validate = (e) => {
const value = Number(e.target.value);
const nameAsNum = Number(e.target.name);
const prevState = [...values];
prevState.find(item => item.id === nameAsNum).value = value >= 64 ? 64 : value
setValues(prevState);
}
return (
<div>
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div>
<input
value = {values[0].value}
name = {1}
onChange = {validate}
/>
<input
value = {values[1].value}
name = {2}
onChange = {validate}
/>
<input
value = {values[2].value}
name = {3}
onChange = {validate}
/>
<input
value = {values[3].value}
name = {4}
onChange = {validate}
/>
</div>
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('react')
);
<div id="react"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js"></script>