React(小白入門)

React Native.jpeg

前言:篇幅較長,需要耗費一些時間和精力哈??

起步

npx create-react-app my-app // 1.創(chuàng)建項目
cd my-app // 2.打開項目
npm start // 3.啟動項目
npm run eject // 4.暴露配置項

目錄

├── README.md ?檔
├── public 靜態(tài)資源
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src 源碼
├── App.css
├── App.js 根組件
├── App.test.js 
├── index.css 全局樣式
├── index.js ???件
├── logo.svg
└── serviceWorker.js pwa?持
├── package.json npm 依賴

入口文件定義

webpack.config.js

React和ReactDom

import React from 'react' 
import ReactDom from 'react-dom'

// JSX => React.createElement(...)
ReactDom.render(<h2>Hello React</h2>,document.querySelector('#root'))

React:負責(zé)邏輯控制,數(shù)據(jù) -> VDOM
ReactDOM:渲染實際DOM,VDOM -> DOM
React使用JSX描述UI
babel-loader把JSX編譯成相應(yīng)的JS對象,React.createElement再把這個JS對象構(gòu)造成React需要的虛擬dom

JSX

JSX是JavaScript的一種語法擴展,其格式比較像模板語言,但事實上完全是在JavaScript內(nèi)部實現(xiàn)的。JSX可以很好的描述UI,能夠有效提高開發(fā)效率。

  • 基本使用
// 表達式{}的使用
const name = 'Cherry'
const jsx = <div>hello,{name}</div>
React.render(jsx,document.querySelector('#root'))
  • 函數(shù)
// 函數(shù)也是合法表達式
const obj = {
  firstName: 'Harry',
  lastName: 'Potter'
}
function formatName(name) {
  return name.firstName + '-' + name.lastName
}
const jsx = <div>hello ,{formatName(obj)}</div>
  • 對象
// jsx是js對象,也是合法表達式
const greet = <div>Cherry</div>
const jsx = (
  <div>
    <div>hello</div>
    {greet}
  </div>
)
  • 條件語句
const show = false;
const greet = <div>Cherry</div>
const jsx = (
 <div>
  {show ? greet : '登錄'}
  {show && greet}
</div>
)
  • 數(shù)組
// 數(shù)組會被當(dāng)作一組元素對待,數(shù)組中存放一組jsx可用于顯示列表數(shù)據(jù)
const arr = [1,2,3]
const jsx = (
  <ul>
    // diff的時候,會先比較type類型,然后是key,所以同級同類型元素,key值必須唯一
    {arr.map(item => (<li key={item}>{item}</li>))}
  </ul>
)
  • 屬性
import logo from './logo.png';
const jsx = (
  <div>
    // 靜態(tài)值用雙引號,動態(tài)值用花括號;class、for等要特殊處理
    <img src={logo} className="logo" style={{width:100,height:100}} />
  </div>
)
  • 模塊化
// index.js
// 命名空間 css模塊化,創(chuàng)建index.module.css
import style from './index.module.css'
const jsx = (
  <div className=style.logo>Pink</div>
)
// index.module.css
.logo {
  width: 100px;
  height: 50px;
  color: pink;
}

組件

組件,從概念上類似于JavaScript函數(shù)。它接受任意的入?yún)ⅲ础皃rops”),并返回用于描述頁面展示內(nèi)容的React元素。
組件有兩種形式:class組件和function組件

  • class組件
    class組件通常擁有狀態(tài)生命周期,繼承于Component,實現(xiàn)render方法,下面我們用class組件來寫一個小例子
// ClassComponent.js
// 導(dǎo)入React以及成員組件Component
import React, { Component } from 'react'
export default class ClassComponent extends Component {
  constructor(props) {
    super(props)
    this.state = {
      date: new Date()
    }
  }
  componentDidMount() {
    // 組件掛載之后啟動定時器每秒更新狀態(tài)
    this.timer = setInterval(() => {
      // 使用setState來更新狀態(tài)
      this.setState({
        date: new Date()
      })
    },1000)
  }
  componentWillUnmount() {
    // 組件卸載前停?定時器
    clearInterval(this.timer)
  }
  render() {
    return (
      <div>{this.state.date.toLocaleTimeString()}</div>
    )
  }
}

  • function組件
    函數(shù)組件通常無狀態(tài),僅關(guān)注內(nèi)容展示,返回渲染結(jié)果即可。

從React16.8開始引入了hooks,函數(shù)組件也能夠擁有狀態(tài)。

// FunctionComponent.js
import React, {useState, useEffect} from 'react'
export function FunctionComponent(props) {
  const [date,setDate] = useState(new Date())
  // 相當(dāng)于 componentDidMount、componentDidUpdate、componentWillUnmount的集合
  useEffect(() => { // 副作用
    const timer = setInterval(() => { 
      setDate(new Date())
    },1000)
    return () => clearInterval(timer) // 組件卸載時執(zhí)行
  },[]) 
  return (
    <div>
      {date.toLocalTimeString()}
    </div>
  )
}

setState的使用

setState(partialState, callback)
1.partialState: object|function 用于產(chǎn)生與當(dāng)前state合并的子集
2.callback : function state更新之后被調(diào)?。

import的使用(拐個彎??)

import語法引用模塊時,如何正確使用{}
現(xiàn)在有兩個模塊分別為A.js,B.js

  • import不使用花括號
// A.js
export default 88
// B.js 
import A from './A' // 只有在如上A.js中有默認導(dǎo)出的export default語法時才會生效
// 不使用{}來引用模塊的情況下,import模塊時的命名是隨意的,如下:
import A from './A'
import sameA from './A'
import xxx from './A'
// Because 它總是會解析到A.js中默認的export default
  • import 使用花括號
// A.js
export const A = 88
// B.js
import { A } from './A' // 只有在如上模塊A.js中有命名導(dǎo)出為A的export name的代碼
import { A } from './A'  // 成功引入,因為A.js中有命名為A的export
import { sameA } from './A' // 引入失敗,因為A.js中沒有命名為sameA的export
import { xxx } from './A'  // 同上
// Because 明確聲明了命名導(dǎo)出后,在另一個js中使用{}引入模塊時,import時的模塊命名是有意義的
// 上述代碼正確執(zhí)行,如下
// A.js
export const A = 88
export const sameA = 99
export const xxx = xxx

??Warning??: 一個模塊只能有一個默認導(dǎo)出export default,但是可以任意命名導(dǎo)入很多次,也可以一次性都導(dǎo)入,例如:

// B.js
import A, { sameA, xxx } from './A'
// 這里我們使用導(dǎo)入默認導(dǎo)出A,以及命名導(dǎo)出sameA和xxx
// 我們也可以在導(dǎo)入的時候重命名導(dǎo)入
import B, {sameA as sameB, xxx as bbb} from './A'

??? 小結(jié)一下:模塊的默認導(dǎo)出通常用在導(dǎo)入整個模塊的內(nèi)容,而命名導(dǎo)出用于導(dǎo)入一些有用的公共方法

生命周期

生命周期方法,用于組件不同階段執(zhí)行自定義功能。在組件被創(chuàng)建并插入到DOM時(即掛載中階段mounting),組件更新時,組件取消掛載或從DOM中刪除時,都有可以使用的生命周期方法

  • React V16.3之前的生命周期
// LifeCyclePage.js
import React, { Component } from "react";
import PropTypes from "prop-types";

export default class LifeCyclePage extends Component {
  static defaultProps = {
    // msg: "hello",
  };
  static propTypes = {
    // msg: PropTypes.string.isRequired,
  };
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
    console.log("constructor");
  }
  componentWillMount() {
    console.log("componentWillMount");
  }
  componentDidMount() {
    console.log("componentDidMount");
  }
  shouldComponentUpdate(nextProps, nextState) {
    const { count } = nextState;
    console.log("shouldComponentUpdate", nextState);
    // return true 執(zhí)行更新操作,return false 返回組件運行時
    return count !== 3;
  }
  componentWillUpdate() {
    console.log("willComponentUpdate");
  }
  componentDidUpdate() {
    console.log("componentDidUpdate");
  }
  setCount = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    console.log("render", this.props);
    const { count } = this.state;
    return (
      <div>
        <h3>Lifecycle</h3>
        <h4>{count}</h4>
        <button onClick={this.setCount}>改變count</button>
        // {count % 2 && <Child count={count} />}
        <Child count={count} />
      </div>
    );
  }
}

class Child extends Component {
  componentWillReceiveProps(nextProps) {
    console.log("componentWillReceiveProps", nextProps);
  }
  componentWillUnmount() {
    console.log("componentWillUnmount");
  }
  render() {
    console.log("Child render");
    const { count } = this.props;
    return (
      <div>
        <h3>Child</h3>
        <p>{count}</p>
      </div>
    );
  }
}

  1. shouldComponentUpdate -> return true
    執(zhí)行順序: constructor => componentWillMount => render => componentDidMount => shouldComponentUpdate => willComponentUpdate => render => componentDidUpdate => over??
    ?? componentWillReceiveProps(初次渲染的時候不執(zhí)行,只有在已掛載的組件接收新的props的時候,才執(zhí)行)
    ?? componentWillUnmount(組件卸載之前,常用在清除定時器等等...)
  2. shouldComponentUpdate -> return false
    執(zhí)行順序:constructor => componentWillMount => render => componentDidMount => shouldComponentUpdate => over??
  • React V16.4之后的生命周期
    打開控制臺的Warning,如下
    Warning.png

V17可能被廢棄的三個生命周期函數(shù)用getDerivedStateFromProps替代,目前使用的話加上UNSAFE_:
?? componentWillMount
?? componentWillReceiveProps
?? componentWillUpdate
引入兩個新的生命周期函數(shù):
?? static getDerivedStateFromProps
?? getSnapshotBeforeUpdate

如果不想手動給將要廢棄的生命周期加上UNSAFE_前綴,可以用以下命令:
npx react-codemod rename-unsafe-lifecycles <path>
新引入的兩個生命周期函數(shù)
  • getDerivedStateFromProps

static getDerivedStateFromProps(props,state)
這個生命周期函數(shù)會在調(diào)用render方法之前調(diào)用,并且在初始掛載及后續(xù)更新時都會被調(diào)用。它應(yīng)返回一個對象來更新state,如果返回null則不更新任何內(nèi)容。
??Warning??:不管原因是什么,都會在每次渲染前觸發(fā)此方法。這與UNSAFE_componentWillReceiveProps形成對比,后者僅在父組件重新渲染時觸發(fā),而不是在內(nèi)部調(diào)用setState時。

  • getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(prevProps,prevState)
在render之后,在componentDidUpdate之前
這個生命周期函數(shù)在最近一次渲染輸出(提交到DOM節(jié)點)之前調(diào)用。它使得組件能在發(fā)生更改之前從DOM中捕獲一些信息(例如,滾動位置)。此生命周期的任何返回值將作為參數(shù)傳遞給 componentDidUpdate(prevProps,prevState,snapshot)

接下來我們看一下執(zhí)行順序
import React, { Component } from "react";
import PropTypes from "prop-types";

export default class LifeCyclePage extends Component {
  static defaultProps = {
    // msg: "hello",
  };
  static propTypes = {
    // msg: PropTypes.string.isRequired,
  };
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
    console.log("constructor");
  }
// 在render之后,在componentDidUpdate之前
 getSnapshotBeforeUpdate(prevProps, prevState, snapshot) {
    console.log("getSnapshotBeforeUpdate", prevProps, prevState, snapshot);
    // return null;
    return {
      msg: "hello,我是getSnapshotBeforeUpdate",
    };
  }
  // 在調(diào)用render方法之前調(diào)用,并且在初始掛載及后續(xù)更新時都會被調(diào)用
  static getDerivedStateFromProps(props, state) {
    console.log("getDerivedStateFromProps");
     // return null; // 不更新任何內(nèi)容
    const { count } = state;
    return count > 5 ? { count: 0 } : null; // 更新state
  }
  // UNSAFE_componentWillMount() {
  //   console.log("componentWillMount");
  // }
  componentDidMount() {
    console.log("componentDidMount");
  }
  shouldComponentUpdate(nextProps, nextState) {
    const { count } = nextState;
    console.log("shouldComponentUpdate", nextState);
    // return false;
    return true;
  }
  // UNSAFE_componentWillUpdate() {
  //   console.log("willComponentUpdate");
  // }
  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log("componentDidUpdate", prevProps, prevState, snapshot);
  }
  setCount = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    console.log("render", this.props);
    const { count } = this.state;
    return (
      <div>
        <h3>Lifecycle</h3>
        <h4>{count}</h4>
        <button onClick={this.setCount}>改變count</button>
        {/* {count % 2 && <Child count={count} />} */}
        <Child count={count} />
      </div>
    );
  }
}

class Child extends Component {
  // UNSAFE_componentWillReceiveProps(nextProps) {
  //   console.log("componentWillReceiveProps", nextProps);
  // }
  componentWillUnmount() {
    console.log("componentWillUnmount");
  }
  render() {
    console.log("Child render");
    const { count } = this.props;
    return (
      <div>
        <h3>Child</h3>
        <p>{count}</p>
      </div>
    );
  }
}

組件復(fù)合

組件復(fù)合可以非常敏捷的自定義組件的外觀和行為,這種方式更明確和安全。如果組件之間有公用的非UI邏輯,應(yīng)該將他們抽取為js模塊導(dǎo)入使用而不繼承。日常開發(fā)中我們經(jīng)常會涉及到組件復(fù)用的例子,例如頭部和底部復(fù)用,下面是一個小的demo??

// HomePage.js
import React, { Component } from "react";
import Layout from "./Layout";
export default class HomePage extends Component {
  render() {
    return (
      // showTopBar -> 是否展示頂部欄 
      // showBottomBar -> 是否展示底部欄
      // title -> 標題
      <Layout showTopBar={false} showBottomBar={true} title={"我的商城"}>
        {/* <div>
          <h3>HomePage</h3>
        </div> */}
        // 具名插槽
        {{
          content: (
            <div>
              <h3>HomePage</h3>
            </div>
          ), // 通過jsx寫頁面內(nèi)容
          txt: "這是一個文本", // 傳文本
          btnClick: () => console.log("call me"), // 傳方法
        }}
      </Layout>
    );
  }
}
// Layout.js
import React, { Component } from "react";
import TopBar from "../components/TopBar"; // 頂部欄組件
import BottomBar from "../components/BottomBar"; // 底部欄組件

export default class Layout extends Component {
  componentDidMount() {
    const { title = "商城" } = this.props;
    document.title = title;
  }
  render() {
    const { children, showTopBar, showBottomBar } = this.props;
    console.log("children", children);
    return (
      <div>
        {showTopBar && <TopBar />}
        <h3>{children.content}</h3>
        {showBottomBar && <BottomBar />}
        <h5>{children.txt}</h5>
        <button onClick={children.btnClick}>點我</button>
      </div>
    );
  }
}

Redux

Redux是負責(zé)組織state的工具,提供可預(yù)測的狀態(tài)管理,不僅僅是用于React。下面我們就來了解一下什么場景下使用redux,redux應(yīng)該怎么使用????

  • ?? 使用場景
  1. 有著相當(dāng)大量的、隨著時間變化的數(shù)據(jù);
  2. state需要有一個單一可靠數(shù)據(jù)來源;
  3. 把所有state放在最頂層組件中無法滿足需求;
  4. 某個組件的狀態(tài)需要共享...
  • ?? 如何使用

安裝Redux

npm install redux --save

??累加器??

  1. 需要一個store來存儲數(shù)據(jù);
  2. store里的reducer初始化state并定義state修改規(guī)則;
  3. 通過dispatch一個action來提交對數(shù)據(jù)的更改;
  4. action提交到reducer函數(shù)里,根據(jù)傳入的action的type,返回新的state

創(chuàng)建store,src/store/ReduxStore.js

import { createStore } from "redux";
// 定義state初始化和修改規(guī)則,reducer是一個純函數(shù)
function counterReducer(state = 0, action) {
  // console.log("state", state);
  switch (action.type) {
    case "ADD":
      return state + 1;
    case "MINUS":
      return state - 1;
    default:
      return state;
  }
}
const store = createStore(counterReducer);
export default store;

創(chuàng)建ReduxPage

import React, { Component } from "react";
import store from "../store/";

export default class ReduxPage extends Component {
  componentDidMount() {
    // 訂閱狀態(tài)變更
    // store.subscribe(() => {
    //   console.log("state發(fā)生變化了");
    //   this.forceUpdate(); // 強制刷新
    // });
  }
  render() {
    console.log("store", store);
    return (
      <div>
        <h3>ReduxPage</h3>
        <p>{store.getState()}</p>
        <button
          onClick={() => {
            store.dispatch({ type: "ADD" });
          }}
        >
          add
        </button>
      </div>
    );
  }
}

在src/index.js的render里訂閱狀態(tài)變更

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import store from "./store";
ReactDOM.render(<App />, document.getElementById("root"));

store.subscribe(() => {
  console.log("state更新了");
  ReactDOM.render(<App />, document.getElementById("root"));
});

??小結(jié)一下??

  1. 通過createStore創(chuàng)建store
  2. reducer初始化、修改狀態(tài)函數(shù)
  3. getState 獲取狀態(tài)值
  4. dispatch 提交更新
  5. subscribe 變更訂閱

react-redux

react-redux從名字上來看就是為react量身定做的,接下來我們來了解一下如何安裝和如何使用react-redux

  • 安裝
npm install react-redux --save
  • 使用

react-redux提供來兩個api:
?? 1.Provider 為后代組件提供store
?? 2. connect 為組件提供數(shù)據(jù)和變更方法

全局提供store,index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import store from "./store";
import { Provider } from "react-redux";
ReactDOM.render(
  // 通過Provider跨層級傳遞把store傳給后代
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

獲取狀態(tài)數(shù)據(jù),ReactReduxPage.js

import React, { Component } from "react";
import { connect } from "react-redux";
export default connect(
  // mapStateToProps 狀態(tài)映射 把state映射到props
  (state) => ({ num: state }),
  // mapDispatchToProps 派發(fā)事件映射 把dispatch映射到props)
  {
    add: () => ({ type: "ADD" }),
  }
)(
  class ReactReduxPage extends Component {
    render() {
      const { num, dispatch, add } = this.props;
      console.log("props", this.props);
      return (
        <div>
          <h3>{num}</h3>
          <h3>ReactReduxPage</h3>
          {/* <button onClick={() => dispatch({ type: "ADD" })}>add</button> */}
          {/* 方法比較多的時候*/}
          <button onClick={add}>add</button>
        </div>
      );
    }
  }
);

?? 另一種寫法

class ReactReduxPage extends Component {
  render() {
    const { num, add, minus } = this.props;
    return (
      <div>
        <h3>{num}</h3>
        <h3>ReactReduxPage</h3>
        <button onClick={minus}>minus</button>
        <button onClick={add}>add</button>
      </div>
    );
  }
}
// mapStateToProps 狀態(tài)映射 把state映射到props
const mapStateToProps = (state) => {
  return {
    num: state,
  };
};
// mapDispatchToProps 派發(fā)事件映射 把dispatch映射到props)
const mapDispatchToProps = {
  add: () => {
    return { type: "ADD" };
  },
  minus: () => {
    return { type: "MINUS" };
  },
};
// connect中的參數(shù):state映射和事件映射
export default connect(mapStateToProps, mapDispatchToProps)(ReactReduxPage);

react-router

react-router包含三個庫,分別 react-router、react-router-domreact-native。
?? react-router提供最基本的路由功能,實際應(yīng)用我們不會直接安裝react-router,而是根據(jù)應(yīng)用運行的環(huán)境選擇安裝react-router-dom(在瀏覽器中使用)或react-router-native(在rn中使用)
?? react-router-domreact-router-native都依賴react-router,所以在安裝時,react-router也會自動安裝,創(chuàng)建web應(yīng)用

  • 安裝
npm install --save react-router-dom
  • 基本使用

react-router中奉行一切皆組件的思想
?? 路由器 -> Router、
?? 鏈接 -> Link、
?? 路由 -> Route
?? 獨占 -> Switch、
?? 重定向 -> Redirect
?? ...
?? 都是以組件形式存在

  • 舉個??
// RouterPage.js
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

export default class RouterPage extends Component {
  render() {
    return (
      <div>
        <h3>RouterPage</h3>
        <Router>
          <Link to="/">首頁</Link>
          <Link to="/user">用戶中心</Link>
          {/* 渲染的三種方式,優(yōu)先級 children > component > render  */}
          <Route
            exact
            path="/"
            component={HomePage}
            children={() => <div>child</div>}
            render={() => <div>render</div>}
          />
          <Route path="/user" component={UserPage} />
        </Router>
      </div>
    );
  }
}

class HomePage extends Component {
  render() {
    return (
      <div>
        <h3>HomePage</h3>
      </div>
    );
  }
}
class UserPage extends Component {
  render() {
    return (
      <div>
        <h3>UserPage</h3>
      </div>
    );
  }
}

Route渲染內(nèi)容的三種方式:
?? 優(yōu)先級:children > component > render 這三種是互斥的關(guān)系

?? children: func
不管location是否匹配,你都需要渲染一些內(nèi)容,這時候可以用children,除此之外和render的工作方法一樣
?? render: func
用render的時候,調(diào)用的只是一個函數(shù),只有在location匹配的時候渲染
?? component: component
只有在location匹配的時候渲染

  • 404頁面

為了更好的用戶體驗,設(shè)定一個沒有path的路由在路由列表最后面,表示一定匹配

// RouterPage.js
import React, { Component } from "react";
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";

export default class RouterPage extends Component {
  render() {
    return (
      <div>
        <h3>RouterPage</h3>
        {/* 獨占路由:添加Switch表示僅匹配一個 */}
        <Switch>
          <Router>
           <Link to="/">首頁</Link>
            <Link to="/user">用戶中心</Link>
            {/* 渲染的三種方式,優(yōu)先級 children > component > render  */}
             {/* 根路由要添加exact,實現(xiàn)精確匹配 */}
            <Route
              exact
              path="/"
              component={HomePage}
              children={() => <div>child</div>}
              render={() => <div>render</div>}
            />
            <Route path="/user" component={UserPage} />
            <Route component={EmptyPage} />
          </Router>
        </Switch>
      </div>
    );
  }
}
class HomePage extends Component {
  render() {
    return (
      <div>
        <h3>HomePage</h3>
      </div>
    );
  }
}
class UserPage extends Component {
  render() {
    return (
      <div>
        <h3>UserPage</h3>
      </div>
    );
  }
}
class EmptyPage extends Component {
  render() {
    return (
      <div>
        <h3>EmptyPage-404</h3>
      </div>
    );
  }
}

PureComponent

PureComponent -> 純組件

  • 實現(xiàn)性能優(yōu)化(淺比較)
    缺點:必須要用class形式,而且要注意是淺比較即僅作對象的淺層?較,如果對象中包含復(fù)雜的數(shù)據(jù)結(jié)構(gòu),則有可能因為?法檢查深層的差別,產(chǎn)?錯誤的?對結(jié)果。所以僅在你的props 和 state 較為簡單時,才使? React.PureComponent ,或者在深層數(shù)據(jù)結(jié)構(gòu)發(fā)?變化時 調(diào)? forceUpdate() 來確保組件被正確地更新
import React, { Component, PureComponent } from "react";
// PureComponent 內(nèi)置了shouldComponentUpdate的比較
export default class PureComponentPage extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      // 可實現(xiàn)性能優(yōu)化
      count: 0,
     // 實現(xiàn)不了,PureComponent只能實現(xiàn)淺比較
      obj: {
        num: 1,
      },
    };
  }
  setCount = () => {
    this.setState({
      count: 1000,
      obj: {
        num: 1000,
      },
    });
  };
  // shouldComponentUpdate(nextProps, nextState) {
  //   // 性能優(yōu)化,只有值變化了才會更新
  //   return nextState.count !== this.state.count;
  // }
  render() {
    const { count } = this.state;
    console.log("render");
    return (
      <div>
        <h3>PureComponentPage</h3>
        <button onClick={this.setCount}>{count}</button>
      </div>
    );
  }
}
  • PureComponent于Component的比較

PureComponentComponent很相似。區(qū)別在于React.Component并未實現(xiàn)shouldComponentUpdate,而PureComponent中以淺層對比 propstate的方式實現(xiàn)了該函數(shù)。

不間斷更新,未完待續(xù)...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容