React Hooks 是 React 16.8 的新增特性。它可让你在不编写 class 的状况下使用 state 以及其余的 React 特性。react
前言
本篇主要以讲几个经常使用的api为主。api
1.useState
这个例子用来显示一个计数器。当你点击按钮,计数器的值就会增长,如今咱们的写法以下,数组
class Example extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } render() { return ( <div> <p>You clicked {this.state.count} times</p> <button onClick={() => this.setState({ count: this.state.count + 1 })}> Click me </button> </div> ); } }
这是咱们所熟悉的写法,替换成useState后ide
import React, { useState } from 'react'; function Example() { // 声明一个叫 "count" 的 state 变量 const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
- 1.首先经过在函数组件里调用useState()来给组件添加一些内部 state,(React 会在重复渲染时保留这个 state)。
- 2.useState()能够传入一个参数,传入的参数就是初始的state,在上面例子当中,0就是初始值。【这个初始 state 参数只有在第一次渲染的会被用到。】
- 3.useState() 会返回一对值:当前状态和一个让你更新它的函数(你能够在事件处理函数中或其余一些地方调用这个函数,它相似 class 组件的 this.setState,可是它不会把新的 state 和旧的 state 进行合并。)
- 4.能够经过useState声明多个state变量,以下
function ExampleWithManyStates() { // 声明多个 state 变量! const [age, setAge] = useState(42); const [fruit, setFruit] = useState('banana'); const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]); // ... }
2.useEffect
useEffect 就是一个 Effect Hook,给函数组件增长了操做反作用的能力。它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具备相同的用途,只不过被合并成了一个 API。函数
依然是先上例子ui
class Example extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } componentDidMount() { document.title = `You clicked ${this.state.count} times`; } componentDidUpdate() { document.title = `You clicked ${this.state.count} times`; } render() { return ( <div> <p>You clicked {this.state.count} times</p> <button onClick={() => this.setState({ count: this.state.count + 1 })}> Click me </button> </div> ); } }
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); // 至关于 componentDidMount 和 componentDidUpdate: useEffect(() => { document.title = `You clicked ${this.state.count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
-
1.默认状况下,React 会在每次渲染后调用反作用函数 —— 包括第一次渲染的时候。this
-
2.反作用函数还能够经过返回一个函数来指定如何“清除”反作用。它的执行顺序是,每次页面更新前,先执行return的函数,而后在执行useEffect里面的内容。spa
import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); useEffect(() => { console.log(`You clicked ${count} times`); return () => { console.log('每次页面更新前,我会先被执行'); } }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
- 3.跟 useState 同样,你能够在组件中屡次使用 useEffect,所以经过使用 Hook,你能够把组件内相关的反作用组织在一块儿(例如建立订阅及取消订阅),而不要把它们拆分到不一样的生命周期函数里。
- 4.useEffect还能够传入第二个参数,指定当某个值发生变化的时候,才触发反作用.
useEffect(() => { document.title = `You clicked ${count} times`; }, [count]); // 仅在 count 更改时更新
- 5.若是想执行只运行一次的 effect(仅在组件挂载和卸载时执行),能够传递一个空数组([])做为第二个参数。
3.useReducer
useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。(若是你熟悉 Redux 的话,就已经知道它如何工做了。)code
// reducer.js export const initialState = {count: 0}; export default (state, action) => { switch (action.type) { case 'increment': return {count: state.count + 1}; case 'decrement': return {count: state.count - 1}; default: throw new Error(); } } // Counter.js import React, { useReducer } from 'react'; import reducer, { initalState } from './reducer.js'; function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <div> <button onClick={() => dispatch({type: 'increment'})}>+</button> <button onClick={() => dispatch({type: 'decrement'})}>-</button> </div> ); }
4.useContext
接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。component
具体使用查看这篇文章。