react hooks
六叶草~ 人气:0背景
介绍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
加载全部内容