资讯专栏INFORMATION COLUMN

React开发中提升幸福度的一些小技巧

smartlion / 1149人阅读

摘要:又一篇来自日常开发的汇总各位客官请对号入席,店小二逐一上菜。解决方案有很多种,例如把字符串数组等重组对象数组,每个元素设置一个唯一等。另外有个方式推荐使用生成唯一的数组,和数据数组一起使用,省去提交数据时再重组数组。

</>复制代码

  1. 又一篇来自日常开发的汇总:各位客官请对号入席,店小二逐一上菜。
第一道菜:回锅肉

react数组循环,基本都会设置一个唯一的key,表格的对象数组循环一般没什么问题,数据基本都会有一个id。那有种情况就比较坑了,出现在表单形式的页面结构中,对某个数组进行增删改操作,一般对于非对象数组而言,没有id,可能很多人会偷懒,循环的时候,直接设置数组的下标index作为key,当出现增删改时候,就会出现数据对不上或者重新渲染组件的问题等。解决方案有很多种,例如把字符串数组等重组对象数组,每个元素设置一个唯一id等。另外有个方式:推荐使用shortid生成唯一key的数组,和数据数组一起使用,省去提交数据时再重组数组。

</>复制代码

  1. import React from "react";
  2. import shortid from "shortid";
  3. class Demo extends React.Component {
  4. constructor(props) {
  5. super(props);
  6. this.state = {
  7. data: ["a", "b", "c"]
  8. }
  9. this.dataKeys = this.state.data.map(v => shortid.generate());
  10. }
  11. deleteOne = index => { // 删除操作
  12. const { data } = this.state;
  13. this.setState({ data: data.filter((v, i) => i !== index) });
  14. this.dataKyes.splice(index, 1);
  15. }
  16. render() {
  17. return (
    • {
    • data.map((v, i) =>
    • this.deleteOne(i)}
    • key={this.dataKeys[i]}
    • >
    • {v}
    • )
    • }
  18. )
  19. }
  20. }
  21. // 稍微抽取,可以封装一个通用的组件
第二道菜:番茄炒蛋

通过判断值是否存在来控制元素是否显示,一般三目运算可以达到此效果,最简单的还是用短路的写法:

</>复制代码

  1. // 不错
  2. const flag = "something";
  3. flag &&
  4. // 很好
  5. // 注意一般可能上面写法多一些,但当flag为0 的时页面上会显示0,用!!将其转为boolean避免坑,
  6. // 代码也更规范
  7. const flag = "something";
  8. !!flag &&
第三道菜:酸辣土豆丝

使用组件,传递props:

</>复制代码

  1. const { data, type, something } = this.state;

也许另外一种传递方式更简洁:

</>复制代码

  1. const { data, type, something } = this.state;
第四道菜:清炒时蔬

组件的props有时候会定义很多,但是调用组件传递props的时候又想一个个传,不想一次性传递一个option对象,通过扩展运算符和解构赋值可以简化此操作:

</>复制代码

  1. const Demo = ({ prop1, prop2, prop3, ...restProps }) => (
  2. xxxx
  3. { restProps.something }
  4. )
  5. // 父组件使用Demo
第五道菜:小吃-糍粑

一般改变state值的一种方式:

</>复制代码

  1. const { data } = this.state;
  2. this.setState({ data: {...data, key: 1 } });

另外一种可以通过callback的方式改变state的值

</>复制代码

  1. this.setState(({ data }) => ({ data: {...data, key: 1 } }));

还可以:

</>复制代码

  1. this.setState((state, props) => {
  2. return { counter: state.counter + props.step };
  3. });
第六道菜:水煮肉片

React 性能优化有很多种方式,那常见的一种就是在生命周期函数shouldComponentUpdate里面判断某些值或属性来控制组件是否重新再次渲染。

判断一般的字符串,数字或者基础的对象,数组都还是比较好处理,那嵌套的对象或者数组就比较麻烦了,对于这种,可以转成字符串处理,但属性值的位置不同时,那就无效了。

推荐使用lodash(或者其他的类似库)的isEqual对嵌套数组或对象进行判断(相比其他方式更简单些)

</>复制代码

  1. shouldComponentUpdate(nextProps, nextState) {
  2. if (_.isEqual(nextState.columns, this.state.columns)) return false;
  3. return true;
  4. }
第七道菜:干锅兔

创建弹层的三种方式:

普通组件通过state和样式控制,在当前组件中显示弹层-每次引入组件并且render里面控制显示,挂载节点在某组件里面

</>复制代码

  1. // 弹层
  2. const Dialog = () =>
    弹层
  3. // 某组件
  4. render() {
  5. return (
  6. this.state.showDialog &&
  7. )
  8. }

2.通过Portals创建通道,在根节点外部挂载组件-但还是需要每次引入并且在render里面调用

</>复制代码

  1. // 弹层
  2. class Dialog extends React.Component {
  3. constructor(props) {
  4. super(props);
  5. this.el = document.createElement("div");
  6. }
  7. componentDidMount() {
  8. modalRoot.appendChild(this.el);
  9. }
  10. componentWillUnmount() {
  11. modalRoot.removeChild(this.el);
  12. }
  13. render() {
  14. return ReactDOM.createPortal(
  15. this.props.children ||
    xxxx
    ,
  16. this.el,
  17. );
  18. }
  19. }
  20. // 某组件
  21. render() {
  22. return (
  23. this.state.showDialog &&
  24. )
  25. }

3.推荐使用ReactDom.render创建弹层-挂载根节点外层,使用也更方便

</>复制代码

  1. // demo
  2. let dialog;
  3. class Dialog {
  4. show(children) { // 显示
  5. this.div = document.createElement("div");
  6. document.body.appendChild(this.div);
  7. ReactDom.render(children ||
    xxxx
    , this.div);
  8. }
  9. destroy() { // 销毁
  10. ReactDom.unmountComponentAtNode(this.div);
  11. this.div.parentNode.removeChild(this.div);
  12. }
  13. }
  14. export default {
  15. show: function(children) {
  16. dialog = new Dialog();
  17. dialog.show(children);
  18. },
  19. hide: xxxxx
  20. };
  21. // 某组件
  22. import Dialog from "xxx";
  23. alert = () => {
  24. Dialog.show(xxxx);
  25. }
  26. render() {
  27. return (
  28. )
  29. }
第八道菜:火烧肉

render props是现在很流行的一种渲染方式,通过回调函数,渲染子组件,参数可为父组件的任意属性值(官网也有相应的介绍)新版的contextApi也采用了这个模式。

很多种场景使用此方式的做法:

</>复制代码

  1. // 权限控制组件,只需要封装一次connect,
  2. // 通过render props向子组件传递权限
  3. class AuthWidget extends Component {
  4. render() {
  5. return this.props.children(this.props.auth);
  6. }
  7. }
  8. const mapStateToProps = state => {
  9. const { auth } = state;
  10. return { auth: state.auth };
  11. };
  12. export default connect(mapStateToProps)(AuthWidget);
  13. // 其他组件使用
  14. auth.edit && 编辑}
  15. />
  16. // 使用antd的form时
  17. const Test = ({ form, children }) => {
  18. return children(form);
  19. };
  20. const FormTest = Form.create()(Test);
  21. class Demo extends Component {
  22. render() {
  23. return (
  24. xxxxx
  25. { form => {
  26. this.form = form;
  27. return (
  28. {getFieldDecorator("field", xxx)(
  29. )}
  30. )
  31. }}
  32. )
  33. }
  34. }
第九道菜:粉丝白菜虾仁汤

子组件改变父组件的state方式有很多种,可以在父组件设置一个通用函数,类似:setParentState,通过子组件回调处理时,就可以更方便的统一处理:

</>复制代码

  1. // 父组件
  2. state = {
  3. data: {}
  4. }
  5. setParentState = obj => {
  6. this.setState(obj);
  7. }
  8. // 子组件
  9. onClick = () => {
  10. this.props.setParentState({ data: xxx });
  11. }
第十道菜:麻婆豆腐

永远不要直接设置state的值:this.state.data = { a: 1 }。这个会导致几个问题:
1:组件不会重新渲染 2:shouldComponentUpdate(nextProps, nextState) 函数里面 this.state的值是已经改变了,和nextState的值相同。

举个栗子:

</>复制代码

  1. // wrong
  2. const { data } = this.state;
  3. data.a = 1; // 等价于this.state.data.a = 1;
  4. this.setState({ data }); // shouldComponentUpdate里面观察到 this.state 和nextState的值是相同的
  5. // 此时函数里面性能相关的优化是无效的
  6. // correct 需要用到当前state值的写法
  7. this.setState(state => ({ data: {...state.data, a: 1} }))

</>复制代码

  1. 各位客官,菜已上齐,请慢用

    react相关讨论,请加Q群:743490497

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97654.html

相关文章

  • JS 可以提升幸福度的技巧

    本文主要介绍一些JS中用到的小技巧,可以在日常Coding中提升幸福度,将不定期更新~ 1. 类型强制转换 1.1 string强制转换为数字 可以用*1来转化为数字(实际上是调用.valueOf方法)然后使用Number.isNaN来判断是否为NaN,或者使用 a !== a 来判断是否为NaN,因为 NaN !== NaN 32 * 1 // 32 ds * 1 ...

    tain335 评论0 收藏0
  • 前端方便面

    摘要:技术前端布局推进剂间距规范化利用变量实现令人震惊的悬浮效果很棒,但有些情况不适用布局说可能是最全的图片版学习网格布局使用的九大误区图解布局布局揭秘和中新增功能探索版本迭代论基础谈展望对比探究绘图中撤销功能的实现方式即将更改的生命周期几道高 技术 CSS 前端布局推进剂 - 间距规范化 利用CSS变量实现令人震惊的悬浮效果 Flexbox 很棒,但有些情况不适用 CSS布局说——可能是最...

    liaoyg8023 评论0 收藏0
  • 前端方便面

    摘要:技术前端布局推进剂间距规范化利用变量实现令人震惊的悬浮效果很棒,但有些情况不适用布局说可能是最全的图片版学习网格布局使用的九大误区图解布局布局揭秘和中新增功能探索版本迭代论基础谈展望对比探究绘图中撤销功能的实现方式即将更改的生命周期几道高 技术 CSS 前端布局推进剂 - 间距规范化 利用CSS变量实现令人震惊的悬浮效果 Flexbox 很棒,但有些情况不适用 CSS布局说——可能是最...

    DevWiki 评论0 收藏0
  • 提升开发幸福感的10条JS技巧

    摘要:作者陈大鱼头鱼头总结一些能够提高开发效率的技巧,这些技巧很实用,觉得挺好,想推荐给大家,所以有了这篇文章。如果此时正在看文章的你也有类似的技巧心得,不妨在下方留言来分享给大家。 作者:陈大鱼头 github: KRISACHAN 鱼头总结一些能够提高开发效率的JS技巧,这些技巧很实用,觉得挺好,想推荐给大家,所以有了这篇文章。 生成随机UID const genUid = () ...

    muddyway 评论0 收藏0
  • 【前端词典】提高幸福感的 9 个 CSS 技巧

    摘要:使用归类重复样式和重复变量一样,重复的样式也可以归类。解决方案可以使用如下的写法两端对齐姓名手机号码账号密码效果如下相关文章输出计划最近总有朋友问我相关的问题,因此接下来我会输出篇相关的文章,希望对大家有一定的帮助。前言 在这篇文章我会介绍 9 个使你的 CSS 更加简洁优雅的使用技巧。这些技巧小生经常使用,觉得挺高效实用,所以也就有了这篇文章。 9 个 CSS 技巧 特此声明,这里说的...

    番茄西红柿 评论0 收藏0

发表评论

0条评论

smartlion

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<