Javascript React中重复代码的简化
在React中,有没有最佳实践来简化以下内容Javascript React中重复代码的简化,javascript,reactjs,design-patterns,Javascript,Reactjs,Design Patterns,在React中,有没有最佳实践来简化以下内容 getInitialState: function () { return { checkbox1: false, checkbox2: false, checkbox3: false, ... }; }, selectCheckbox1: function () { this.setState({ checkbox1: !this.state.checkbox1 }); }, select
getInitialState: function () {
return {
checkbox1: false,
checkbox2: false,
checkbox3: false,
...
};
},
selectCheckbox1: function () {
this.setState({
checkbox1: !this.state.checkbox1
});
},
selectCheckbox2: function () {
this.setState({
checkbox2: !this.state.checkbox2
});
},
selectCheckbox3: function () {
this.setState({
checkbox3: !this.state.checkbox3
});
},
...
render: function () {
return (
<div>
<input type="checkbox" checked={this.state.checkbox1} onChange={this.selectCheckbox1} />
<input type="checkbox" checked={this.state.checkbox2} onChange={this.selectCheckbox2} />
<input type="checkbox" checked={this.state.checkbox3} onChange={this.selectCheckbox3} />
...
</div>
);
}
getInitialState:函数(){
返回{
复选框1:false,
复选框2:错误,
复选框3:错误,
...
};
},
选择复选框1:功能(){
这是我的国家({
checkbox1:!this.state.checkbox1
});
},
选择复选框2:功能(){
这是我的国家({
checkbox2:!this.state.checkbox2
});
},
选择复选框3:功能(){
这是我的国家({
checkbox3:!this.state.checkbox3
});
},
...
渲染:函数(){
返回(
...
);
}
例如,我可以对状态使用数组而不是单个字段,并创建一个通用函数,该函数使用索引参数来区分要更新的复选框:
const Checkboxes = React.createClass({
getInitialState: function () {
return {
checkboxes: [false, false, false, ...]
};
},
selectCheckbox: function (index) {
let checkboxes = this.state.checkboxes.slice();
checkboxes[index] = !checkboxes[index];
this.setState({
checkboxes: checkboxes
});
},
render: function () {
return (
<div>
<input type="checkbox" checked={this.state.checkboxes[0]} onChange={() => this.selectCheckbox(0)} />
<input type="checkbox" checked={this.state.checkboxes[1]} onChange={() => this.selectCheckbox(1)} />
<input type="checkbox" checked={this.state.checkboxes[2]} onChange={() => this.selectCheckbox(2)} />
...
</div>
);
}
});
const复选框=React.createClass({
getInitialState:函数(){
返回{
复选框:[假,假,假,…]
};
},
selectCheckbox:函数(索引){
让checkboxes=this.state.checkboxes.slice();
复选框[索引]=!复选框[索引];
这是我的国家({
复选框:复选框
});
},
渲染:函数(){
返回(
此选项。选择复选框(0)}/>
此选项。选择复选框(1)}/>
此选项。选择复选框(2)}/>
...
);
}
});
我对React和JavaScript是新手,所以我不知道这里幕后到底发生了什么。第二个比第一个好吗?首选哪种方法?为什么?第二种方法肯定比第一种方法更好。你可以放心 除此之外,还可以通过使用阵列贴图渲染复选框,而无需每次在渲染函数中重复它们
render: function () {
return (
<div>
{this.state.checkboxes.map((c, i) => {
return (
<input key={i} type="checkbox" checked={c} onChange={() => this.selectCheckbox(i)} />
);
})}
</div>
);
}
render:function(){
返回(
{this.state.checkbox.map((c,i)=>{
返回(
此选项。选择复选框(i)}/>
);
})}
);
}
我会这样做:
class App extends Component {
constructor(props) {
super(props);
this.state = {
checkboxes: {
cheese: false,
lettuce: false,
tomatoe: false
}
};
}
handleChange = e => {
const checkboxId = e.target.id;
this.setState({
checkboxes: {
...this.state.checkboxes,
[checkboxId]: !this.state.checkboxes[checkboxId]
}
});
};
render() {
return (
<div>
{Object.entries(this.state.checkboxes).map(([key, val]) => {
return (
<div key={key}>
<input
type="checkbox"
checked={val}
id={key}
onChange={this.handleChange}
/>
<label>
{key}
</label>
</div>
);
})}
</div>
);
}
}
类应用程序扩展组件{
建造师(道具){
超级(道具);
此.state={
复选框:{
奶酪:错,
莴苣:错,
托马托:错
}
};
}
handleChange=e=>{
const checkboxId=e.target.id;
这是我的国家({
复选框:{
…此.state.checkbox,
[checkboxId]:!this.state.checkbox[checkboxId]
}
});
};
render(){
返回(
{Object.entries(this.state.checkbox).map([key,val])=>{
返回(
{key}
);
})}
);
}
}
这使得事情更加明确,更容易理解,并且还有一个额外的好处,就是每次渲染时不创建新的匿名函数。我更喜欢命名复选框(在对象中,而不是数组中),就像第一个示例中一样。但这可能因用例而异。如前所述,让它们像数组一样未命名,可以提供映射到它们的好处 我将这样做以减少回调函数声明的重复(无需将复选框值存储在数组中):
const复选框=React.createClass({
getInitialState:函数(){
返回{
复选框1:false,
复选框2:错误,
复选框3:错误
};
},
选择复选框:功能(复选框NR){
//返回带有checkboxNr集的回调
return()=>{
这是我的国家({
[checkboxNr]:!this.state[checkboxNr]
});
}
},
渲染:函数(){
const{checkboxes1,checkboxes2,checkboxes3}=this.state;
返回(
);
}
});
在每个渲染上创建新的匿名函数有哪些缺点?什么时候进行垃圾收集?@JoshBroadhurst允许底层组件在shouldComponentUpdate
中比较道具是最佳做法。匿名函数总是不同的,明白了吗。谢谢在map调用中仍然有一个匿名函数(([key,val])=>{…}
),但它不是作为道具传递的。这个匿名函数是如何影响渲染周期的?它被称为每个渲染周期,这就是为什么要使用handleChange=e=>{
而不是handleChange:function(e){
你能解释一下这个语法:const{checkbox1,checkbox2,checkbox3}=this.state;
从onChange prop的命名函数返回匿名函数是否与直接在onChange prop中使用匿名函数具有相同的垃圾收集性能问题?@JoshBroadhurst。当然,也许我应该提到这一点。在本例中,是对象。this.state
是包含所有属性。根据您引用的行,我们挑选出与名称checkbox1、checkbox2和checkbox3匹配的属性。然后它们在范围中作为变量提供。这相当于编写const checkbox1=this.state.checkbox1;const checkbox2=this.state.checkbox2
等@JoshBroadhurst关于垃圾收集我不知道,但我猜他们也有类似的行为。但我也猜,在大多数情况下,垃圾收集也不会是一个问题。(虽然这是从Veery有限的经验讲的。)这个问题仍然没有解决。是吗?
const Checkboxes = React.createClass({
getInitialState: function () {
return {
checkbox1: false,
checkbox2: false,
checkbox3: false
};
},
selectCheckbox: function (checkboxNr) {
// return a callback with the checkboxNr set
return () => {
this.setState({
[checkboxNr]: !this.state[checkboxNr]
});
}
},
render: function () {
const {checkboxes1, checkboxes2, checkboxes3} = this.state;
return (
<div>
<input type="checkbox" checked={checkboxes1} onChange={ this.selectCheckbox("checkbox1") } />
<input type="checkbox" checked={checkboxes2} onChange={ this.selectCheckbox("checkbox2") } />
<input type="checkbox" checked={checkboxes3} onChange={ this.selectCheckbox("checkbox3") } />
</div>
);
}
});