react hooks总结
一:useState
用法:变量,对象,数组,方法
其实useState的参数可以抽象成一个你想让它返回给你什么的对象(普通类型,对象,方法,数组)
function Buttonc(){
const [count,setCount] = useState(0)
const [obj,setObj] = useState({name:‘wuchao’})
const [arr,setArr] = useState([1,2,3])
const [fun,setFun] = useState(()=>{
return {name:‘wc’+count}
})
return (
{count}
<Button onClick={()=>setCount(count+1)}>add+
{obj.name}
<Button onClick={()=>setObj({…obj,name:‘wcc’})}>obj
{arr}
<Button onClick={()=>setArr(()=>{
arr.push(4)
return […arr]
})}>add+
{fun.name}
<Button onClick={()=>setFun(()=>{
return {name:‘张益达’}
})}>add+
}
二:useEffect
function Buttonc() {
//相当于class的componentDidMount,componentDidUpdate,componentWillUnmount
//副作用的意思(dom操作,数据请求,组件更新)
//参数有俩个(回调函数,数组可不写)数组是需要监听的
//当数组不写state更新就会被只想,想监听一部分数组【count】,不想监听只在第一次熏染后执行一次写【】
const [count,setCount]=useState(0)
useEffect(()=>{
console.log(count+‘componentDidMount’)
},[count])
useEffect(()=>{
console.log(count+'componentDidMount')
return ()=>{
console.log('componentWillUnmount')
}
},[])
return (<div>
{count}
<Button onClick={()=>setCount(count+1)}>add+</Button>
</div>)
}
三:useRef
function Buttonc() {
//获取dom
const divRef = useRef(null)
//在current里存值
const classNameValue = useRef(null)
return (
<Button onClick={()=>{
divRef.current.focus()
console.log(divRef.current)
console.log(classNameValue)
}}>add+
}
四:useContext,createContext
父组件
import {createContext} from ‘react’
export let MyContext = createContext();
子组件
import React, {useContext} from ‘react’
import {MyContext} from ‘./CreatContext’
function Childbody(){
const obj = useContext(MyContext)
return (
{obj.count}
{obj.name}
}
export default Childbody
使用
import React, {useState} from ‘react’;
import {Button} from ‘antd’
import {MyContext} from ‘./CreatContext’
import ChildContext from ‘./childContext’
function Buttonc() {
const [count,setCount] = useState(0)
return (
<MyContext.Provider value={{count,name:‘wcw’}}>
</MyContext.Provider>
<Button onClick={()=>{setCount(count+1)
}}>add+
}
五:useMemo
useMemo参数类似useEffect,功能类型shouldComponentUpdate,控制组件是否会因为state或者props变化而熏染
子组件
import React, {useMemo} from ‘react’
function Childbody({count,num}){
let obj = useMemo(()=>{
return {count,num}
},[num])
return (
{obj.count}
{obj.num}
}
export default Childbody
父组件
import React, {useState,useMemo} from ‘react’;
import {Button} from ‘antd’
import ChildContext from ‘./childContext’
function Buttonc() {
const [count,setCount] = useState(0)
const [num,setNum] = useState(0)
let res=useMemo(()=>{
return {count,num}
},[count])
return (<div>
<div>---count {res.count}-----num: {res.num}</div>
<ChildContext count={res.count} num={res.num} />
<Button onClick={()=>{setCount(count+1)
}}>add+count</Button>
<Button onClick={()=>{setNum(num+1)
}}>add+num</Button>
</div>)
}
六:useCallback
避免重复渲染,提高性能,同样是运用缓存技术不同的是,返回是个函数,参数类似useMemo
import React, {useState,useCallback} from ‘react’;
import {Button} from ‘antd’
function Buttonc() {
const [count,setCount] = useState(0)
const [num,setNum] = useState(0)
let call=useCallback(()=>{
return num
},[count])
return (<div>
<div>---count {count}-----num: {call()}</div>
<Button onClick={()=>{setCount(count+1)
}}>add+count</Button>
<Button onClick={()=>{setNum(num+1)
}}>add+num</Button>
</div>)
}
七:forwardRef
父组件获取子组件具体dom
import React, {useState,forwardRef,useRef} from ‘react’;
import {Button} from ‘antd’
const Forword = forwardRef((props,ref)=>{
return (
<>
</>
)
})
function Buttonc() {
const el = useRef(null)
return (
<Button onClick={()=>{console.log(el.current)
}}>add+num
}
八:useImperativeHandle
可是自定义暴露给父组件ref内容,可以向上传值或者方法
import React, {useState,forwardRef,useRef,useImperativeHandle} from ‘react’;
import {Button} from ‘antd’
const Forword = forwardRef((props,refp)=>{
const refInput = useRef(null)
const [count,setCount] = useState(0)
const [num,setNum] = useState(0)
useImperativeHandle(refp,()=>({
name:‘forword’,
focus:()=>{
refInput.current.focus();
},
count
}),[num])
return (
<>
<Button onClick={()=>{setCount(count+1)
}}>add+count
<Button onClick={()=>{setNum(num+1)
}}>add+num
</>
)
})
function Buttonc() {
const el = useRef(null)
return (
<Button onClick={()=>{
console.log(el)
el.current.focus()
}}>add+num
}
九:useLayoutEffect
用法同useEffect,只是比他更早执行。容易阻塞慎用
十:useReducer
useReducer是一个函数,第一个参数reducer,第二个是初始值,第三个是init
返回值,第一个是state,第二个是dispatch
import React, {useReducer} from ‘react’;
import {Button} from ‘antd’
function Buttonc() {
const [state,dispatch] = useReducer((state,action)=>{
switch (action.type) {
case ‘setName’:
return {
…state,
name:action.name
}
case ‘setAge’:
return {
…state,
age:action.age
}
default:
return state
}
},{name:'wc',age:18})
return (<div>
<div>--name-{state.name}--age-{state.age}</div>
<Button onClick={()=>{
dispatch({
type:'setName',
name:'wuchao'
})
}}>add+name</Button>
<Button onClick={()=>{
dispatch({
type:'setAge',
age:25
})
}}>add+age</Button>
</div>)
}
应用:基于createContext和useReducer与useContext 开发简易版的redux
请测@babel/plugin-proposal-decorators 装饰器不可以用在函数组件上 ,若可以请告知谢谢
1>Dva.js
import React from ‘react’
import {createContext,useReducer} from ‘react’
export const MyContext = createContext();
const initData = {name:‘wc’,age:18}
const reducer = (state, action)=>{
switch (action.type) {
case ‘setName’:
return {
…state,
name:action.name
}
case ‘setAge’:
return {
…state,
age:action.age
}
default:
return state
}
}
export default (props) =>{
const [state,dispatch] = useReducer(reducer,initData)
console.log(props,‘wcwwchome1’)
return (<MyContext.Provider value={{state,dispatch}}>
{props.children}
</MyContext.Provider>)
}
2>index.js
import React from ‘react’;
import Home from ‘./Home’
import Dva from ‘./Dva’
import My from ‘./My’
function Reducers(props) {
return (<Dva>
<Home title={'dvahahha'} />
<My />
</Dva>)
}
3:Home.js
import React, {Component,useContext} from ‘react’
import {MyContext} from “./Dva”;
import {Button} from ‘antd’
import connect from ‘./connect’
// @connect()
function Childbody(props) {
console.log(props,‘wcwwchome’)
let {state,dispatch} = useContext(MyContext)
return (
—name-{state.name}–age-{state.age}—
<Button onClick={()=>{
dispatch({
type:‘setName’,
name:‘李阳’
})
}}>add+name
<Button onClick={()=>{
dispatch({
type:‘setAge’,
age:38
})
}}>add+age
}
export default Childbody
4>My.js
import React, {Component,useContext} from ‘react’
import {Button} from ‘antd’
import {MyContext} from “./Dva”;
import connect from ‘./connect’
// @connect(true)
function Childbody (){
let {state,dispatch} = useContext(MyContext)
return (
—name-{state.name}–age-{state.age}—
<Button onClick={()=>{
dispatch({
type:‘setName’,
name:‘吴超’
})
}}>add+name
<Button onClick={()=>{
dispatch({
type:‘setAge’,
age:18
})
}}>add+age
}
5>是我尝试模拟dva写connect,可以装饰器不可以写在函数组件上,不给力,若你有方法还请告知。
附上connect.js的代码探讨!
import React,{useContext,Component} from ‘react’
import {MyContext} from ‘./Dva’
export default ()=>{
return (WrapperedComponent)=>{
let {state,dispatch} = useContext(MyContext)
console.log(1111,‘22’)
return class extends Component{
render() {
return <WrapperedComponent {…this.props} />
}
}
}
}