#reactjs #typescript
#reactjs #typescript
Вопрос:
У меня есть состояние, в котором мне нужно обновить несколько кнопок во вложенном объекте, а затем использовать dispatch для redux для обновления хранилища, но по-прежнему не нашел для этого хорошего решения:
У меня есть следующий интерфейс, который я хотел бы отправить данным, следуя его структуре:
interface Object {
name: string;
buttons: {
button1: number;
button2: number;
button3: number;
button4: number;
};
}
Поэтому я хочу избежать решения, в котором мое состояние обновления состояния было бы таким:
const [name, setName] = useState("");
const [button1, setButton1] = useState(0);
const [button1, setButton1] = useState(0);
const [button1, setButton1] = useState(0);
const [button1, setButton1] = useState(0);
И я хочу отправить свою форму, где у меня было бы состояние, подобное этому:
const [object, setObject] = useState({
name: "";
buttons: {
button1: 0;
button2: 0;
button3: 0;
button4: 0;
};
})
function submit() {
dispatch( {
name: "";
buttons: {
button1: 3;
button2: 6;
button3: 8;
button4: 4;
})
}
поэтому, когда я пытаюсь увеличивать и уменьшать свои кнопки, я обычно делаю так, чего хочу избежать:
// increment
onClick={() => setButton1(button1 1)}
// decrement
onClick={() => setButton1(button1 - 1)}
Итак, есть ли лучшее решение для этого?
Комментарии:
1. Вот где
useReducer
может помочь. Вы можете просто просто отслеживать, с какой кнопки он нажал. И обновить только эту кнопку
Ответ №1:
Полный пример
import React, { useState } from "react";
export default function App() {
const [buttons, setButtons] = useState([0, 0, 0, 0])
const handleClick = (event) => {
const key = event.target.name
// Copy state
const newButtons = [...buttons]
// Update state
newButtons[key] = 1
// Submit state
setButtons(newButtons)
console.log(buttons)
}
return (
<div>
<button name="1" onClick={handleClick}>1 Button</button>
</div>
);
}
PS. Если вы хотите полностью клонировать вложенный объект, вам нужно создать функцию cloneObject или использовать библиотеку Immer, clone(cloneDeep) func из Lodash
Полный пример со свойством name
import React, { useState } from "react";
import cloneDeep from "lodash.clone"
export default function App() {
const [state, setState] = useState({
name: "",
buttons: [0, 0, 0, 0]
})
const handleClick = (event) => {
const key = event.target.name
// Copy state
const newState = cloneDeep(state)
// Update state
newState.buttons[key] = 1
// Submit state
setState(newState)
console.log(state)
}
return (
<div>
<button name="1" onClick={handleClick}>1 Button</button>
</div>
);
}
Комментарии:
1. не получилось по-вашему, не могли бы вы объяснить подробнее?
2. Обновлено сообщение и добавлены два примера с библиотекой и без. Если вы не хотите использовать библиотеку-клон, вы можете создать свою собственную, но я думаю, что это не рекомендуется.