处理多个复选框和复杂的数据结构(reactjs)

时间:2018-11-10 19:41:39

标签: javascript arrays reactjs object ecmascript-6

由于我是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 :(得分:0)

我希望我可以看到您的完整代码。 但是,如果我想建议您进行任何更改:

  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} });
 };

请注意,setState()函数中的{... currentAnswers,newAnswers}正在将currentAnswers与newAnswers中的新更改合并。即newAnswers将覆盖外部数组中的特定对象。 这是功能性的处理方式。

答案 1 :(得分:0)

我不是第一个,但是这是我的测试版本

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)))