react 常用规范和经验

(1)业务代码里面的异步请求需要 try catch

ajax 请求,使用 try catch,错误提示后端返回,并且做一些失败后的状态操作例如进入列表页,我们需要一个 loading 状态,然后去请求数据,可是失败之后,也需要把 loading 状态去掉,把 loading 隐藏的代码就写在 finally 里面。

getStudentList = async () => {
  try {
    this.setState({
      loading: true,
      isEmpty: false
    });
    await getStudentList({});
    this.setState({
      loading: false,
      isEmpty: true
    });
  } catch (e) {
    // TODO
    console.log(e)
  } finally {
    //  失败之后的一些兜底操作
    this.setState({
      loading: false,
      isEmpty: true
    });
  }
};
(2) for-in 中一定要有 hasOwnProperty 的判断(即禁止直接读取原型对象的属性)
//bad
const arr = [];
const key = '';

for (key in obj) {
  arr.push(obj[key]);
}

//good
const arr = [];
const key = '';

for (key in obj) {
  if (obj.hasOwnProperty(key)) {
    arr.push(obj[key]);
  }
}
(3)第三方库函数的使用
try catch 包裹,防止第三方库的出现错误,导致整个程序崩溃

/*
 * Echart 用于代绘制图表,但当其自身发生错误时,可能影响到业务代码的执行
 */
// bad
const iniDom = document.getElementById('init-container');
const echartObj = echarts.init(iniDom);
this.setState(
  {
    echartObj
  },
  () => {
    const { echartObj } = this.state;
    // 更新图表
    echartObj.setOption(CHART_CONFIG, true);
  }
);

// good
try {
  const iniDom = document.getElementById('init-container');
  const echartObj = echarts.init(iniDom);
  this.setState(
    {
      echartObj
    },
    () => {
      const { echartObj } = this.state;
      // 更新图表
      echartObj.setOption(CHART_CONFIG, true);
    }
  );
} catch (error) {
  // TODO
}
(4)防止 xss 攻击

input,textarea 等标签,不要直接把 html 文本直接渲染在页面上,使用 xssb 等过滤之后再输出到标签上;

import { html2text } from 'xss';
render(){
  <div
  dangerouslySetInnerHTML={{
    __html: html2text(htmlContent)
  }}
/>
}
(5)在组件中获取真实 dom

使用 16 版本后的 createRef()函数

class MyComponent extends React.Component<iProps, iState> {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  render() {
    return <input type="text" ref={this.inputRef} />;
  }

  componentDidMount() {
    this.inputRef.current.focus();
  }
}
(6)代码细粒度的思考

总结四句话。我们在写组件或者函数的的时候,

  • 工具函数和业务逻辑抽离;
  • 表单校验和业务抽离;
  • 事件函数和业务抽离;
  • ajax和业务抽离;

例如有些页面是通过location.href跳转的,我们有些业务逻辑等都是放到didmountMount,但是后期改需求,可能要用react-router进行跳转,可能要改的逻辑就会很多了,所以函数抽离出来,需求更新就少改一点代码。
如果还不确定如何划分函数的细粒度,我有个建议。使用过两次以上的代码,要抽离组件或者函数,两次的可以不用

(7)a标签安全问题

使用a标签打开一个新窗口过程中的安全问题。新页面中可以使用window.opener来控制原始页面。如果新老页面同域,那么在新页面中可以任意操作原始页面。如果是不同域,新页面中依然可以通过window.opener.location,访问到原始页面的location对象
在带有target="_blank"的a标签中,加上rel="noopener"属性。如果使用window.open的方式打开页面,将opener对象置为空。

var newWindow = window.open();
newWindow.opener = null;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值