обрабатывать несколько флажков и сложную структуру данных (реагировать) - PullRequest
0 голосов
/ 10 ноября 2018

Поскольку я довольно новичок в React и также не являюсь большим экспертом по JS, особенно по ES6, мне интересно, как сделать мой код (который работает) красивее и улучшить его рефакторинг.

Я хочу обработать несколько флажков в форме и сохранить текущее значение в объекте состояния. Поскольку флажки сгруппированы, я хочу, чтобы структура отвечала следующим задачам:

{  
   "isLoaded":true,
   "answeredTasks":{  
      "1":[  
         "green",
         "blue",
         "red"
      ],
      "5":[  
         "car",
         "cat",
         "house"
      ]
   }
}

Вот мой метод onChange с флажком:

  checkBoxOnChange = e => {
    let currentAnswers = this.state.answeredTasks;

    let element = e.currentTarget;

    // if it is the first answer checked
    if (currentAnswers[element.name] === undefined) {
      currentAnswers[element.name] = [];
    }

    // if uncheck
    if (!element.checked) {
      const index = currentAnswers[element.name].indexOf(element.value);
      currentAnswers[element.name].splice(index, 1);
    } else {
      currentAnswers[element.name].push(element.value);
    }

    this.setState({ answeredTasks: currentAnswers });
  };

Можете ли вы сказать мне, как улучшить мой метод, особенно с ES6? В основном я боролся с созданием структуры данных.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Я не первый, но вот моя версия с тестом

static changeAnswers = ({target: {name, value, checked}}) => 
  checked
    ? { ...answeredTasks, ...{ [name]: [...(answeredTasks[name] || []), value] } }
    : {
        ...answeredTasks,
        ...{ [name]: (answeredTasks[name] || []).filter(e => e !== value) }
      }

checkBoxOnChange = e => {
  const {answeredTasks} = this.state
  this.setState({answeredTasks: myComponent.changeAnswers(e)})
}

const answeredTasks = { "1": ["green", "blue", "red"] }

const elements = [
  { name: "1", value: "green", checked: false },
  { name: "1", value: "black", checked: true },
  { name: "2", value: "lol", checked: true },
  { name: "2", value: "lol", checked: false }
]

const click = ({ name, value, checked }) =>
  checked
    ? { ...answeredTasks, ...{ [name]: [...(answeredTasks[name] || []), value] } }
    : {
        ...answeredTasks,
        ...{ [name]: (answeredTasks[name] || []).filter(e => e !== value) }
      }

elements.map(element => console.log(click(element)))
0 голосов
/ 11 ноября 2018

Я предпочел бы увидеть весь ваш код. Но если бы я хотел предложить вам какие-либо изменения:

  1. В общем, избегайте использования «let» в вашем коде и вместо этого используйте «const». Таким образом, вы избегаете мутирования данных, что является лучшей отраслевой практикой, и документация React настоятельно рекомендует.

  2. Избегайте использования методов splice / push / pop, которые изменяют данные, и вместо этого используйте функции массива, такие как filter / map / some / every и т.д. объект.

Вот изменение, которое вы должны сделать:

checkBoxOnChange = e => {
    const currentAnswers = this.state.answeredTasks;
    const element = e.target;

    const newAnswers = !element.checked ?
        (currentAnswers[element.name] || []).filter(val => val !== element.value) :
        (currentAnswers[element.name] || []).concat(element.value);  

    this.setState({ answeredTasks: {...currentAnswers, newAnswers} });
 };

Обратите внимание, что {... currentAnswers, newAnswers} внутри функции setState () объединяет currentAnswers с новыми изменениями в newAnswers. то есть newAnswers перезапишет конкретный объект во внешнем массиве. Это функциональный способ ведения дел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...