Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

从react render里面的箭头函数说开去 #21

Open
Jeffersondyj opened this issue May 25, 2019 · 0 comments
Open

从react render里面的箭头函数说开去 #21

Jeffersondyj opened this issue May 25, 2019 · 0 comments

Comments

@Jeffersondyj
Copy link
Owner

起因

组里面某同学在render里面写了一个类似这种组件:

`
const {onClick, value} = this.props;
return (
    <Comp onClick={() => onClick(value)} />
);
`

然后触发了我厂的代码规范,具体是这样写的:JS-998,JSX props should not use arrow functions

于是某些情况下,他可以这样写:

`
onClick = () => {
     const {onClick, value} = this.props;
     onClick(value);
}

render() {
    return (
         <Comp onClick={this.onClick} />
    );
}
`

不过他依旧对于要另外写一个类成员方法耿耿于怀。况且有时候是函数式定义的stateless组件,这样还不得不改成用Class方式定义,也显得特别sb。

另外一种苟且的法门是:某些网上帖子推崇的,“推荐使用提取子组件或在 HTML 元素中传递数据的方式来避免绑定。”那就要用data-set了,并操作dom了。这里代码过于苟且,就不贴sample了。

经过

做了一番实验后发现:箭头函数在每次 render 时都会重新分配(和使用 bind 的方式相同)。所以,尽管我将组件写为 PureComponent,如果组件的props里面有父组件给的箭头函数,会导致子组件为所有的实例传递了一个新的函数。所以每个用户实例都会重新 render。

结论:

避免在 render 中使用箭头函数和绑定。否则会打破 shouldComponentUpdate 和 PureComponent 的性能优化。

image

解决

该怎么整呢?我review了一下组内其他同学的code,发现这种困扰之前也有。有的甚至直接不用箭头函数了,而是另外写原生function...

我的建议是使用useMemo useCallback等新特性,顺便在组内分享时安利给了所有组员。

`
const {onClick, value} = this.props;
const onClickMemo = useCallback(() => onClick(value), [onClick, value]);
return (
    <Comp onClick={onClickMemo} />
);

const computedVal = useMemo(() => 
    props.a + props.b,
    [props.a, props.b]
);
return <div>{computedVal}</div>;
`

useCallback:把匿名回调“存”起来,考虑到匿名方法会被反复重新声明而无法被多次利用,然后容易造成component反复不必要的渲染。

useMemo:从component props中获得原始数据, 计算、转换格式后再显示是非常常见的需求。useMemo可以轻松防止不必要的重复计算。

这俩hook没出之前可以用memoize库,现在可以替换成这个react官方的了~

其他

React组件规范里面我其实也已经写了蛮多,后续因为react版本的升级等缘故,某些当时觉得ok的写法,现在不合适了,后续在那个issue里面再更新吧~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant