问题描述
我正在使用我的React应用程序,并收到此错误
错误JSX道具不应使用箭头功能反应/ jsx-no-bind
这是我运行箭头函数的地方(inClick ):
{this.state.photos.map(tile =>(
< span key = tile.img}>
<复选框
defaultChecked = {tile.checked}
onCheck = {()=> this.selectPicture(tile)}
style = {position:'absolute',zIndex:99,padding:5,backgroundColor:'rgba(255,255,255,0.72)'}}
/>
< GridTile
title = {tile.title}
subtitle = {< span> by< b> {tile.author}< / b>< / span>}
actionIcon = {< IconButton onClick = {()=> this.handleDelete(tile)}>< Delete color =white/>< / IconButton>}
>
< img onClick = {()=> this.handleOpen(tile.img)} src = {tile.img} style = {{cursor:'pointer'}} />
< / GridTile>
< / span>
))}
这是不好的做法,应该避免吗?那么最好的方法是什么?
为什么不应该在JSX props中使用内联箭头功能
在JSX中使用箭头函数或绑定是一个坏的做法,会损害性能,因为每个渲染功能都会重新创建。
-
无论何时创建一个函数,上一个函数都是垃圾回收的。使用内联箭头函数会导致
PureComponent
s,这样可以在动画中创建多个元素。
shouldComponentUpdate 方法中使用
shallowCompare
的组件,无论如何都要重新渲染。由于每次重新创建箭头功能,所以浅比较将会将其标识为对道具的更改,并且组件将重新安装。 正如您在以下2个例子中可以看到的那样 - 当我们使用内联箭头函数时,每次都会重新呈现< Button>
组件(控制台显示
示例1 - PureComponent 无内联处理程序
class Button extends React.PureComponent {render(){const {onClick} = this.props; console.log('render button'); return(< button onClick = {onClick}>点击< / button>); }} class Parent extends React.Component {state = {counter:0} onClick =()=> this.setState((prevState)=>({counter:prevState.counter + 1})); render(){const {counter} = this.state; return(< div>< Button onClick = {this.onClick} />< div> {counter}< / div>< / div>); }} ReactDOM.render(< Parent />,document.getElementById('root'));
< script src =https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js>< / script> < script src =https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js>< / script>< div id =root> ;< / div>
示例2 - PureComponent with inline handler
class Button extends React.PureComponent {render(){const {onClick} = this.props; console.log('render button'); return(< button onClick = {onClick}>点击< / button>); }} class Parent extends React.Component {state = {counter:0} render(){const {counter} = this.state; (< div>< Button onClick = { < / div>< / div>); }} ReactDOM.render(< Parent />,document.getElementById('root'));
< script src =https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js>< / script> < script src =https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js>< / script>< div id =root> ;< / div>
code>这个没有内联箭头函数
-
手动绑定方法在构造函数中:
class Button extends React.Component {
constructor(props,context){
超级(道具,上下文);
this.cb = this.cb.bind(this);
}
cb(){
}
render(){
return(
&按钮onClick = {this.cb}>点击< / button>
);
}
}
-
使用,带箭头功能。由于这是第2阶段提案,因此您需要添加或到您的宝贝配置。 p>
class Button extends React.Component {
cb =()=> {//类属性初始化为一个箭头函数,将其绑定到类
}
render(){
return(
< ; button onClick = {this.cb}>点击< / button>
);
}
}
I'm running lint with my React app, and I receive this error
error JSX props should not use arrow functions react/jsx-no-bind
And this is where I'm running the arrow function (inside onClick):
{this.state.photos.map(tile => (
<span key={tile.img}>
<Checkbox
defaultChecked={tile.checked}
onCheck={() => this.selectPicture(tile)}
style={{position: 'absolute', zIndex: 99, padding: 5, backgroundColor: 'rgba(255, 255, 255, 0.72)'}}
/>
<GridTile
title={tile.title}
subtitle={<span>by <b>{tile.author}</b></span>}
actionIcon={<IconButton onClick={() => this.handleDelete(tile)}><Delete color="white"/></IconButton>}
>
<img onClick={() => this.handleOpen(tile.img)} src={tile.img} style={{cursor: 'pointer'}}/>
</GridTile>
</span>
))}
Is this a bad practice and should be avoided? And what's the best way to do it?
Why you shouldn't use inline arrow functions in JSX props
Using arrow functions or binding in JSX is a bad practice that hurts performance because on each render the function recreated.
Whenever a function is created, the previous function is garbage collected. Rerendering many elements might create jank in animations.
Using an inline arrow function will cause
PureComponent
s, and components that useshallowCompare
in theshouldComponentUpdate
method to rerender anyway. Since the arrow function prop is recreated each time, the shallow compare will identify it as a change to a prop, and the component will rerender.
As you can see in the following 2 examples - when we use inline arrow function, the <Button>
component is rerendered each time (the console shows the 'render button' text).
Example 1 - PureComponent without inline handler
class Button extends React.PureComponent {
render() {
const { onClick } = this.props;
console.log('render button');
return (
<button onClick={ onClick }>Click</button>
);
}
}
class Parent extends React.Component {
state = {
counter: 0
}
onClick = () => this.setState((prevState) => ({
counter: prevState.counter + 1
}));
render() {
const { counter } = this.state;
return (
<div>
<Button onClick={ this.onClick } />
<div>{ counter }</div>
</div>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
<div id="root"></div>
Example 2 - PureComponent with inline handler
class Button extends React.PureComponent {
render() {
const { onClick } = this.props;
console.log('render button');
return (
<button onClick={ onClick }>Click</button>
);
}
}
class Parent extends React.Component {
state = {
counter: 0
}
render() {
const { counter } = this.state;
return (
<div>
<Button onClick={ () => this.setState((prevState) => ({
counter: prevState.counter + 1
})) } />
<div>{ counter }</div>
</div>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
<div id="root"></div>
Binding methods to this
without inlining arrow functions
Binding the method manually in the constructor:
class Button extends React.Component { constructor(props, context) { super(props, context); this.cb = this.cb.bind(this); } cb() { } render() { return ( <button onClick={ this.cb }>Click</button> ); } }
Binding a method using the proposal-class-fields with an arrow function. As this is a stage 2 proposal, you'll need to add the Stage 2 preset or the Class properties transform to your babel configuration.
class Button extends React.Component { cb = () => { // the class property is initialized with an arrow function that binds this to the class } render() { return ( <button onClick={ this.cb }>Click</button> ); } }
这篇关于为什么JSX道具不应该使用箭头功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!