当我开始使用React的时候,我希望自己知道这些技巧【译】

自从2013年5月29日正式发布以来,React.js已经占领了互联网。我和很多开发者的成功都要归功于这个神奇的框架,这已经不是啥秘密了。

Medium上有很多React.js的教程,在我开始使用React.js时,我希望这些教程中有一个可以告诉我以下这些小技巧。

使用arrow function时不需要使用.bind(this)

一般的,当你有一个受控的组件时,你会像以下示例这样做:

class Foo extends React.Component{
  constructor( props ){
    super( props );
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(event){
    // your event handling logic
  }
  render(){
    return (
      <button type="button" 
      onClick={this.handleClick}>
      Click Me
      </button>
    );
  }
}

你在每个方法中都写上.bind(this),因为绝大多数教程都告诉你要这样做。如果你有几个受控组件,你的constructor(){}方法会变得十分臃肿。

作为替代,你可以这样做:

class Foo extends React.Component{
  handleClick = (event) => {
    // your event handling logic
  }
  render(){
    return (
      <button type="button" 
      onClick={this.handleClick}>
        Click Me
      </button>
    );
  }
}

不错吧。

ES6的arrow function使用Lexical Scoping,这允许方法在被触发时访问this

当service workers对你的开发产生阻碍时

Service workers非常适用于一个progressive web app,progressive web app允许离线访问,并且优化在较差网络环境下的用户的体验。

但是当你还没有意识到service worker正在缓存你的静态文件,你会不停地部署你的热更新文件。

不要慌,确保你的src/index.js

// Make sure it's set to unregister
serviceWorker.unregister();

在16.8版本下,这行应该默认是serverWorker.unregister()

但是如果后面版本他们决定再次改变,你要知道去哪里找到这个设置。

在99%的情况下,你不需要eject

Create React App提供了一个选项yarn eject,用于定制你的项目的构建过程。

我记得我尝试着自定义一个构建过程以实现在我们的代码中可以自动关联SVG图片。我花了数个小时的时间尝试着去理解构建过程。最后,我们得到了一个包含SVG标签的导入文件,然后我们加快了网站的加载速度0.0001毫秒。

在你的React项目中使用eject就像为了提高1%的速度,将你正在运行的汽车的引擎盖打开并更换了引擎。

当然了,如果你已经是一个使用Webpack的资深人士,为了适应特殊的项目需求使用自定义构建过程是值得的。

当你尝试按时完成任务时,将你的精力集中在能推进进度的点上。

使用ESlint Auto Fix On Save将会节约大量的时间

你可能从某些地方复制了一些代码,他们的格式给了你沉重的打击(一看就头疼)。因为你无法忍受他们看起来有多丑,你花费时间去手动的添加空格。

使用Visual Studio Code的ESLint插件,可以在保存的时候修复格式。

如何使用呢?

  1. 在你的package.json文件中,添加一些开发环境依赖,然后执行npm i或者yarn:

    "devDependencies": {
    "eslint-config-airbnb": "^17.1.0",
    "eslint-config-prettier": "^3.1.0",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-jsx-a11y": "^6.1.1",
    "eslint-plugin-prettier": "^3.0.0",
    "eslint-plugin-react": "^7.11.0"
    }
  2. 安装ESLint扩展

  3. 开启Auto Fix On Save

你并不需要Redux,styled-components,等等…

每个工具都有它的目的,这就是说,了解不同的工具是有好处的。

If all you have is a hammer, everything looks like a nail — Abraham Maslow

如果你有一把锤子,那么一切都看起来像钉子— Abraham Maslow

你需要考虑你在引入使用这些库所花费的时间,并比较下面几点:

  • 我在尝试解决什么问题?
  • 这个项目可以长久的从这个库中获得好处吗?
  • React是不是提供了相同的,现成的方法?

现在React提供了Context和Hooks,你还需要Redux吗?

当你的用户在较差的网络环境下使用的时候,我墙裂的推荐Redux Offline。

重复事件处理器

如果你不想一遍又一遍的写相同的东西,重写一个事件处理器会是一个很好的选择:

class App extends Component {
 constructor(props) {
  super(props);
  this.state = {
   foo: "",
   bar: "",
  };
 }
 // Reusable for all inputs
 onChange = e => {
  const {
   target: { value, name },
  } = e;

  // name will be the state name
  this.setState({
   [name]: value
  });
 };

 render() {
  return (
   <div>
    <input name="foo" onChange={this.onChange} />
    <input name="bar" onChange={this.onChange} />   
   </div>
  );
 }
}

setState是异步的

曾经愚蠢的我是这样写的:

 constructor(props) {
  super(props);
  this.state = {
   isFiltered: false
  };
 }
 toggleFilter = () => {
  this.setState({
   isFiltered: !this.state.isFiltered
  });
  this.filterData();
 };

 filterData = () => {
  // this.state.isFiltered should be true, but it's not
  if (this.state.isFiltered) {
   // Do some filtering
  }
 };

优化方案一:将state传递下去

toggleFilter = () => {
 const currentFilterState = !this.state.isFiltered;
 this.setState({
  isFiltered: currentFilterState
 });
 this.filterData(currentFilterState);
};
filterData = (currentFilterState) => {
 if (currentFilterState) {
  // Do some filtering
 }
};

优化方案二:在setState的二次回调函数中处理

toggleFilter = () => {
 this.setState((prevState) => ({
  isFiltered: !prevState.isFiltered
 }), () => {
  this.filterData();
 });
};
filterData = () => {
  if (this.state.isFiltered) {
   // Do some filtering
  }
};

结语

这些技巧帮我节省了大量的时间,我相信还有更多这样的秘诀,如果你有其他的,请在评论去与我们分享。

如果你的网站正在尝试与微信平台结合,并期许获得中国10亿以上的用户,请登录 free glossary for commonly used WeChat terms

原文地址:https://medium.freecodecamp.org/what-i-wish-i-knew-when-i-started-to-work-with-react-js-3ba36107fd13

发表评论

电子邮件地址不会被公开。 必填项已用*标注