обновление нескольких кнопок объекта

#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. Обновлено сообщение и добавлены два примера с библиотекой и без. Если вы не хотите использовать библиотеку-клон, вы можете создать свою собственную, но я думаю, что это не рекомендуется.