react-hook簡單使用


 

一、函數式組件創建

function HelloComponent(props, /* context */) {
  return <div>Hello {props.name}</div>
}
ReactDOM.render(<HelloComponent name="Sebastian" />,document.getElementById("mountNode")) 

這里我們可以知道該組件中並沒有自己的狀態,但實際開發中往往需要內部的狀態實現一系列的交互和展示功能.所以我們用class創建組件更多一點.但是,純函數的組件式創建更符合react的思想,於是為了解決狀態問題,完善的函數式組件創建模式出現:react-hook

首先需要明確的一點是,hook中沒有this指針,所以相關的api都需要改變才.

二、常用HOOK API

結合class式組件進行對比

1.組件申明

class:

export default class Text extends React.Component {}

Hook

const Text = {}
export default Text

2.state

 (1)初始化

class

constructor(props) {
    super(props);
    this.state = {
      name: '小明',
age:1 }; }

Hook

const [name, setName] = useState(0);
const [age, setAge] = useState(1);

//name:變量名 初始值是useState()里面額值,相當於name=0,同時又申明了一個函數setName並使其具有監聽name變化然后更新視圖的功能
//setName:傳一個新的name值,並更新至視圖層.可以是一個具有返回值的函數

(2)獲取state值

class

this.state.name
this.state.age

Hook  

const [name, setName] = useState('小明');
const [age, setAge] = useState(1);
useState('小明')//獲取name,自動忽略參數
useState(1)//獲取age,自動忽略參數

(3)修改state值

class

this.setState({age:18})
//實際上是修改的this.state的里面的元素

Hook

setAge(18)
//傳入一個新的age值,自動渲染至視圖層.不同於setState(),只能一次設置一個特定變量.

3.props

用法差不多,只不過hook不用初始化,直接將參數拿來用.

4.生命周期

class

componentWillMount //在渲染前調用,在客戶端也在服務端。

componentDidMount : //在第一次渲染后調用,只在客戶端。之后組件已經生成了對應的DOM結構,可以通過this.getDOMNode()來進行訪問。 如果你想和其他JavaScript框架一起使用,可以在這個方法中調用setTimeout, setInterval或者發送AJAX請求等操作(防止異步操作阻塞UI)。

componentWillReceiveProps //在組件接收到一個新的 prop (更新后)時被調用。這個方法在初始化render時不會被調用。

shouldComponentUpdate //返回一個布爾值。在組件接收到新的props或者state時被調用。在初始化時或者使用forceUpdate時不被調用。
可以在你確認不需要更新組件時使用。

componentWillUpdate//在組件接收到新的props或者state但還沒有render時被調用。在初始化時不會被調用。

componentDidUpdate //在組件完成更新后立即調用。在初始化時不會被調用。

componentWillUnmount//在組件從 DOM 中移除之前立刻被調用。

Hook

生命周期的實質就是回調函數,只不過用不同的生命周期表示不同階段的回調函數.目前Hook只有一個回調函數useEffect(),但是在多個階段觸發

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // 如果你熟悉 React class 的生命周期函數,你可以把 useEffect Hook 看做 componentDidMountcomponentDidUpdate 和 componentWillUnmount 這三個函數的組合。
    document.title = `You clicked ${count} times`;
  });
  
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

 另外,useEffect()還可以手動設置依賴項,它可以接收兩個參數,第一個是函數,第二個是依賴項(數組),第二個參數給的話就依據依賴項時候更改決定是否調用,不給就類似上面的用法.

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  },[count]);
  
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );

5.comtext

   具體的需求就是組件之間的的狀態共享,比如兄弟之間、爺孫之間,跨組件的狀態共享.解決了參數需要逐層往下傳遞的麻煩.

   class

 

// Context 可以讓我們無須明確地傳遍每一個組件,就能將值深入傳遞進組件樹。
// 為當前的 theme 創建一個 context(“light”為默認值)。
const ThemeContext = React.createContext('light');

class App extends React.Component {
  render() {
    // 使用一個 Provider 來將當前的 theme 傳遞給以下的組件樹。
    // 無論多深,任何組件都能讀取這個值。
    // 在這個例子中,我們將 “dark” 作為當前的值傳遞下去。
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// 中間的組件再也不必指明往下傳遞 theme 了。
function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  // 指定 contextType 讀取當前的 theme context。
  // React 會往上找到最近的 theme Provider,然后使用它的值。
  // 在這個例子中,當前的 theme 值為 “dark”。
  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;
  }
} 

Hook

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext); //由於沒有了this,所以我們需要用這個api來獲取context,然后使用.其他的用法一樣

  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}  

6.ref

這里主要針對,ref綁定字符串這種形式的使用.回調函數的用法是一樣的,其根本原因還是Hook並沒有"this.refs"這種獲取ref的方式

class

<input ref="input" />

let inputEl = this.refs.input;//這里拿到對應的ref,然后處理相關邏輯

Hook

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` 指向已掛載到 DOM 上的文本輸入元素
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

7.reducer

class

this.props.dispatch({type:'/api'})

Hook

const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

 待補充

  

  

  

  

  

  

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM