由于我是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? 我主要在创建数据结构方面苦苦挣扎。
谢谢。
答案 0 :(得分:0)
我希望我可以看到您的完整代码。 但是,如果我想建议您进行任何更改:
通常,避免在代码中使用“ let”,而应使用“ const”。这样,您可以避免更改数据(这是行业最佳实践),因此React文档强烈建议这样做。
避免使用会改变数据的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)))