三分钟搞懂react-hooks及实例代码
作者:六叶草~
背景
介绍Hooks之前,首先要说一下React的组件创建方式,一种是类组件
,一种是纯函数组件
,并且React团队希望,组件不要变成复杂的容器,最好只是数据流的管道。开发者根据需要,组合管道即可。也就是说组件的最佳写法应该是函数
,而不是类。
但是我们知道,在以往开发中类组件和纯函数组件的区别是很大的,纯函数组件有着类组件不具备的多种特点:
纯函数组件没有状态
纯函数组件没有生命周期
纯函数组件没有this
这就注定,我们所推崇的函数组件,只能做UI展示的功能,涉及到状态的管理与切换,我们不得不用类组件或者redux,但我们知道类组件的也是有缺点的,比如,遇到简单的页面,代码会显得很重,并且每创建一个类组件,都要去继承一个React实例;至于Redux,更不用多说,很久之前Redux的作者就说过,“能用React解决的问题就不用Redux”。
useState
useState():状态钩子。纯函数组件没有状态,useState()用于为函数组件引入状态。
点击加一效果,分别用类组件和函数组件实现。可以看出用hooks写出的代码更加精简。
const [count,setCount] = useState(0)
;//数组解构,相当于下面三句话
let _useState = useState(0);
let count = _useState[0];
let setState = _useState[1]
类组件
import React,{Component} from "react"; class App1 extends Component{ constructor(props) { super(props); this.state={ count:0 } } addCount(){ this.setState({count:this.state.count+1}) } render() { return( <div> <p>you clicked {this.state.count} times</p> <button onClick={this.addCount.bind(this)}>Click me</button> </div> ) } } export default App1;
函数组件
使用sueState重写上面计数组件。
import React,{useState} from "react"; function App2(){ const [count,setCount] = useState(0);//数组解构 return( <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> </div> ) } export default App2;
多状态声明
使用多条语句声明不同的状态
import React,{useState} from "react"; function App3(){ const [name,setName] = useState('刘备');//数组解构 const [age,setAge] = useState(25); const [sex,setSex] = useState('男') return( <div> <p>姓名:{name}</p> <p>年龄:{age}</p> <p>性别:{sex}</p> </div> ) } export default App3;
useEffect
useEffect():副作用钩子。可以用来更好的处理副作用,如异步请求等,Hooks的useEffect()也是为函数组件提供了处理副作用的钩子。在类组件中我们会把请求放在componentDidMount里面,在函数组件中我们可以使用useEffect()。
useEffect相当于componentDidMount和componentDidUpdate。
缺点:由于它是异步的因此不能实时处理。
类组件中componentDidMount和componentDidUpdate
import React,{Component} from "react"; class App4 extends Component{ constructor(props) { super(props); this.state={ count:0 } } componentDidMount() { console.log(`componentDidMount=>you clicked ${this.state.count}`) } componentDidUpdate() { console.log(`componentDidUpdate=>you clicked ${this.state.count}`) } addCount(){ this.setState({count:this.state.count+1}) } render() { return( <div> <p>you clicked {this.state.count} times</p> <button onClick={this.addCount.bind(this)}>Click me</button> </div> ) } } export default App4;
useEffect模拟类组件中componentDidMount和componentDidUpdate
import React,{useState,useEffect} from "react"; function App5(){ const [count,setCount] = useState(0);//数组解构 useEffect(()=>{ console.log(`useEffect=>you clicked ${count} times`) }) return( <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> </div> ) } export default App5;
useEffect实现componmentWillUnment
先写两个路由跳转页面,并配置路由
import React,{useState,useEffect} from "react"; import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom' function Index(){ return <h2>Index页面</h2> } function List(){ return <h2>List页面</h2> } function App5(){ const [count,setCount] = useState(0);//数组解构 return( <div> <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> </div> <Router> <div> <ul> <li><Link to="/">首页</Link></li> <li><Link to="/list/">list</Link></li> </ul> <Routes> <Route path="/" exact element={<Index/>}/> <Route path="/list/" element={<List/>}/> </Routes> </div> </Router> </div> ) } export default App5;
使用useEffect表示进入页面的状态。
解绑时使用return,这时发现我们点击按钮时也会发生改变,这是因为只要组件发生改变,它就会触发解绑。解决方法使用第二个参数。
import React,{useState,useEffect} from "react"; import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom' function Index(){ useEffect(()=>{ console.log(`useEffect=>Index页面`) return ()=>{ console.log('跳转页面') } }) return <h2>Index页面</h2> } function List(){ useEffect(()=>{ console.log(`useEffect=>List页面`) }) return <h2>List页面</h2> } function App5(){ const [count,setCount] = useState(0);//数组解构 return( <div> <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> </div> <Router> <div> <ul> <li><Link to="/">首页</Link></li> <li><Link to="/list/">list</Link></li> </ul> <Routes> <Route path="/" exact element={<Index/>}/> <Route path="/list/" element={<List/>}/> </Routes> </div> </Router> </div> ) } export default App5;
解绑限制,第二个参数是一个数组,如果数组为空表示页面被销毁触发,如果有变量,表示只有这个变量状态变化才会触发。
import React,{useState,useEffect} from "react"; import { BrowserRouter as Router, Route, Link, Routes } from 'react-router-dom' function Index(){ useEffect(()=>{ console.log(`useEffect=>Index页面`) return ()=>{ console.log('跳转页面') } },[]) return <h2>Index页面</h2> } function List(){ useEffect(()=>{ console.log(`useEffect=>List页面`) }) return <h2>List页面</h2> } function App5(){ const [count,setCount] = useState(0);//数组解构 return( <div> <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> </div> <Router> <div> <ul> <li><Link to="/">首页</Link></li> <li><Link to="/list/">list</Link></li> </ul> <Routes> <Route path="/" exact element={<Index/>}/> <Route path="/list/" element={<List/>}/> </Routes> </div> </Router> </div> ) } export default App5;
父子组件传值useContext
useContext():共享状态钩子。作用就是可以做状态的分发,在React16.X以后支持,避免了react逐层通过Props传递数据。
使用步骤
1、先使用createContext创建上下文
2、然后使用Provider将值给提供出去
3、接收时用useContext接收就可以了
import React,{useState,createContext,useContext} from "react"; const CountContext = createContext(); function Counter(){ let count = useContext(CountContext); return (<h2>{count}</h2>) } function App6(){ const [count,setCount] = useState(0);//数组解构 return( <div> <p>You cliked {count} times</p> <button onClick={()=>{setCount(count+1)}}>Click me</button> <CountContext.Provider value={count}> <Counter/> </CountContext.Provider> </div> ) } export default App6;
useReducer
useReducer():Action钩子
。在使用React的过程中,如遇到状态管理,一般会用到Redux,而React本身是不提供状态管理的。而useReducer()提供了状态管理。首先,关于redux我们都知道,其原理是通过用户在页面中发起action,从而通过reducer方法来改变state,从而实现页面和状态的通信。而Reducer的形式是(state, action) => newstate
。
import React,{useReducer} from "react"; function Reduser(){ const [count,dispath] = useReducer((state,action)=>{ switch (action){ case "add": return state+1 case "sub": return state-1 default: return state } },0) return( <div> <h2>现在的分数是{count}</h2> <button onClick={()=>{dispath('add')}}>add</button> <button onClick={()=>{dispath('sub')}}>sub</button> </div> ) } export default Reduser
到此这篇关于三分钟看完react-hooks的文章就介绍到这了,更多相关react hooks内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!