這些點多是你初學React時須要瞭解的

前言

最近在學習React,這過程當中遇到過許多不明白的地方,所以總結出來分享給你們。瞭解了這些知識後學習React更加容易上手。css

下面的各類概念我都沒有寫得很深刻,只是給你們一個引子,方便你們在學習的過程當中更加體系化,我相信這些都是你們在學習React的時候一定會去了解的知識。html

每一個概念我都附上了我查找學習過程參考的文章,感謝這些大佬的分享。vue

相關知識

一、爲何要引入 React

二、爲何要用 className 而不用 class

三、爲何屬性要用小駝峯

四、爲何 constructor 裏要調用 super 和傳遞 props

五、爲何組件用大寫開頭

六、爲何調用方法要 bind this

七、爲何要 setState,而不是直接 this.state.xx = oo

八、setState 是同步仍是異步相關問題

以上8點是學習React一定繞不過的,由於社區的@桃翁大佬已經總結了,這裏再也不贅述。同時感謝大佬解惑,讓我在學習的時候少走了許多彎路。下面附上原做者的地址。react

新手學習 react 迷惑的點(一)git

新手學習 react 迷惑的點(二)github

九、爲何我下載了react的包還要下載react-dom這個包

react在v0.14以前是沒有「搞分離」的,全部東西都在react裏面。可是後來fb搞出了react-native,因此這以後分離了出來,react包含了Web和Mobile的核心部分,負責DOM部分的分在了react-dom裏面,Mobile部分就分在了react-native裏面。因此咱們在Web開發時除了安裝引入react之外還要安裝引入react-dom。同理在react-router裏面也細分出了react-router-dom和react-router-native。web

參考資料

爲何react和react-dom要分紅兩個包?面試

十、爲何React的生命週期鉤子函數有那麼多版本

React在幾個版本里面迭代過幾回鉤子函數,這裏我先貼幾張圖。vue-router

  • 16.3以前

  • 僅16.3

  • 16.4及之後

我估計目前大多數人用的React版本應該都是16.4及之後的了,因此咱們關注16.4版本後的生命週期鉤子函數。npm

這裏總結下,目前移除的鉤子函數有:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate

而後新版本里麪包括新增的鉤子函數完整以下:

  • static getDerivedStateFromProps
  • getSnapshotBeforeUpdate
  • shouldComponentUpdate
  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount

參考資料

React v16.3以後的組件生命週期函數

我對 React v16.4 生命週期的理解

十一、React能夠建立哪些類型的組件

這個我目前還在摸索學習當中,目前我瞭解到的有這些

一、類組件

使用ES6的class聲明建立,ES5使用的React.createClass方法(這個方法再也不介紹)。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {

    }
  }

  render() {
    return (
      <div>
        <p>This is a react component</p>
      </div>
    )
  }
}
複製代碼

函數式組件(無狀態組件)

React 16.8事後,結合Hooks也能夠進行狀態管理了

使用聲明函數的方式來建立組件。

import React from 'react';

export default function FuncComponentTest(props) {
  return (
    <div>
      <p>這是函數式組件</p>
      <p>{ props.name }</p>
    </div>
  )
}
複製代碼

特色:

一、優勢 無需實例化,無生命週期,只負責渲染,性能更好。若是你的組件沒有涉及到內部狀態,只是用來渲染數據,那麼就用函數式組件,性能較好。 無需綁定當前做用域,咱們使用類組件時須要在constructor或者在JSX的事件裏面使用bind來綁定this。

this.sayHi = this.sayHi.bind(this)

<a onClick={this.sayHi}></a>

或
<a onClick={this.sayHi.bind(this)}>Say Hi</a>
複製代碼

二、缺點 上面的優勢相應就會帶來缺點 沒有實例化,this爲undefined,沒法使用refs;沒有生命週期方法;shouldComponentUpdate方法沒有,重複渲染都無法避免。

PureComponent(純組件)

React v15.3.0中新增的一個特性。

PureReactComponent 組件和 ReactComponent 組件的區別就是它在 shouldComponentUpdate 中會默認判斷新舊屬性和狀態是否相等,若是沒有改變則返回 false,所以它得以減小組件的重渲染。

所以相比於 Component ,PureComponent 有性能上的更大提高:

減小了組件無心義的重渲染(當 state 和 props 沒有發生變化時),當結合 immutable 數據時其優更爲明顯;隔離了父組件與子組件的> 狀態變化;

import React from 'react';

class PureComponentTest extends React.PureComponent {
  render() {
    return (
      <div>
        <p>這是純組件</p>
      </div>
    )
  }
}

export default PureComponentTest;
複製代碼

高階組件

研究中......

參考資料

React 中的各類組件

React PureComponent 使用指南

React 的性能優化(一)當 PureComponent 趕上 ImmutableJS

【react總結(一)】:一次性完全弄懂組件(函數式組件、PureComponent、React.memo、高階組件)

React 中的五種組件形式

【DailyENJS第7期】掌握 React 函數式組件

React(二):類組件、函數式組件

[譯]React函數組件和類組件的差別

React中函數式聲明組件

十二、怎麼進行React的路由管理

使用React開發單頁面項目確定是要用到路由,目前主要是使用react-router,我在查閱的時候有替代方案,叫@reach/router,連接,react-router不像Vue的路由能夠進行集中管理,有時候用起來十分分散。

若是你想實現相似vue-router同樣的管理方式,可使用react-router-config這個小工具來實現,下面我給出示例代碼

import React from 'react';
import { Redirect } from 'react-router-dom'; // 使用這個必定要引入上面那句話import React from 'react';

import Index from '../components/Index';
import LifeCircleFunction from '../components/LifeCircleFunction';
import FunctionComponentTest from '../components/components_test/FuncComponentTest';
import PureComponentTest from '../components/components_test/PureComponentTest';

const routes = [
  {
    path: '/',
    exact: true,
    render: () => {
      return <Redirect to={"/index"}></Redirect>
    }
  },
  {
    path: '/index',
    exact: true,
    component: Index
  },
  {
    path: '/lifecirclefunction',
    exact: true,
    component: LifeCircleFunction
  },
  {
    path: '/functomponenttest/:id',
    exact: true,
    component: FunctionComponentTest
  },
  {
    path: '/purecomponenttest',
    exact: true,
    component: PureComponentTest
  }
]

export default routes;
複製代碼
import React from 'react';
import logo from './logo.svg';
// 這裏建議寫HashRouter as Router這句話,當你想切換成BrowserRouter時不須要處處去修改
import { HashRouter as Router, Link, Switch } from 'react-router-dom';

import { renderRoutes } from 'react-router-config';
import routes from './router/router';

function App() {
  return (
      <div className="App">
        <Router>
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
          </header>
          <hr></hr>
          {/* 跳轉按鈕 */}
          {/* 使用Link標籤時必須使用 HashRouter或者bowserRouter包裹*/}
          <Link to="/lifecircle">
            <button>生命週期函數測試</button>
          </Link>
          <Link to="/functomponenttest/11235?name=lee">
            <button>函數式組件</button>
          </Link>
          <Link to="/purecomponenttest">
            <button>純組件</button>
          </Link>

          {/* 路由 */}
          <Switch>
            { renderRoutes(routes) }
          </Switch>
        </Router>
      </div>
  );
}

export default App;
複製代碼

編程式跳轉

Vue的vue-router除了藉助標籤實現跳轉外,還能夠藉助$router對象實現編程跳轉。

在React裏面咱們須要藉助history對象(非瀏覽器的那個history)來實現跳轉,好比它的push、replace、go方法等。這兒咱們能夠藉助props來獲取到history,注意根組件,通常是叫App這個,this.props對象是空的。

咱們能夠這樣寫

this.props.history.push('/about');
複製代碼

若是你使用的函數組件,若是你想使用history實例的方法,你可使用useHistory這個鉤子,react的版本必須大於16.8才行。

import { useHistory } from 'react-router-dom';
複製代碼
let history = useHistory();
history.push('/about');
複製代碼

參考資料

React Router Config(React 集中配置式路由)

react-router-dom實現全局路由登錄攔截

在react中如何設置路由

官方教程

React-Router動態路由設計最佳實踐

react-router-dom中的BrowserRouter和HashRouter,link與Navlink

react-router/packages/react-router-config

react-router-config 使用與路由鑑權

react-router-config 插件使用和分析

最新 React Router 全面整理

react-router二次封裝實現Vue-router使用方式

React Router 5.1.0使用useHistory作頁面跳轉導航

1三、我該怎麼去管理個人CSS代碼

最基本的方式就是單獨寫在css文件裏面而後再直接在組件裏面import,可是有個問題就是,若是個人類命重複了,就會出現樣式被覆蓋衝突的狀況。這裏有幾種方式能夠實現。

  • 使用命名空間 + BEM 規範
  • CSS in JS
  • CSS Module

我在上面幾個方案中通常用的CSS Module,BEM這種通常用於UI組件庫比較多,CSS in JS在社區中不少開發者也用。關於這幾種方案,已經有大佬詳細講過,見參考資料

參考資料

面試官:你怎麼優雅管理 CSS?

如何在React中優雅的寫CSS

1四、React怎麼實現懶加載

React在16.6版本中加入了一個方法和一個組件來進行懶加載,其中一個是React.lazy(),還有個是React.Suspense。使用方式爲

// 該組件是動態加載的
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    // 顯示 <Spinner> 組件直至 OtherComponent 加載完成
    <React.Suspense fallback={<Spinner />}>
      <div>
        <OtherComponent />
      </div>
    </React.Suspense>
  );
}
複製代碼
  • 注意:這個特性須要瀏覽器支持Promise。

1五、開發單頁面我應該怎麼選擇腳手架

若是你不想過多的折騰,那你選擇官方的create-ract-app基本足夠了,可是官方的腳手架作了許多限制,若是本身搭建環境的話,必須對Webpack周圍的生態比較熟悉才行。

經過方法腳手架生成的項目雖然作了限制,若是你確實想要本身配置,能夠經過npm run eject這個命令來把配置暴露出來,可是這個是不可逆的。

有沒有什麼工具既能夠不破壞react-scripts,同時又能本身配置的工具呢,能夠試一試社區出的react-app-rewired這個工具,使用這個工具的話最好結合customize-cra這個工具一塊兒。

首先咱們安裝好這個兩個工具

npm react-app-rewired customize-cra -D
複製代碼

修改package.json的scripts內容爲如下:

"scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test": "react-app-rewired test",
  "eject": "react-scripts eject"
}
複製代碼

而後在你的項目根目錄新建一個名爲config-overrides.js的文件,這裏我以按需加載ant-design爲例

/* config-overrides.js */

// 這個文件是用來給create-react-app添加額外配置的
const { override, fixBabelImports } = require('customize-cra');

module.exports = override(
  fixBabelImports('import', {  // 按需加載ant-design
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css',
  }),
);

複製代碼

參考資料

如何擴展 Create React App 的 Webpack 配置

react-app-rewired

customize-cra

最後

本文後期會不時地更新,若是有紕漏歡迎你們指正,若是以爲不錯,請你們點個贊再走吧!

相關文章
相關標籤/搜索