hooks
-
hooks介绍
-
什么是hooks
不编写类的情况下使用 state(状态) 和其他 React 功能,hooks是在react16.8新增功能
-
主要解决的问题
1.用于在函数组件中引入状态管理和生命周期方法. 2.取代高阶组件和render props来实现抽象和可重用性. 3.完全脱离'类',便可写出一个全功能的组件.
-
优点
1.避免在被广泛使用的函数组件在后期迭代过程,需要承担一些副作用,而必须重构成类组件. 2.帮助函数组件引入状态管理和生命周期方法; 3.hooks出现之后,我们将复用逻辑取到组件顶层,而不是强行提升到父组件中.这样就能够避免HOC和render props带来的嵌套地域.
-
react中钩子的作用及常用的钩子
从外部引入对象的钩子函数,来做响应的功能.
常用的钩子;
useState():为函数组件引入状态 useEffect():副作用钩子 useReducer():action钩子 useContext():共享状态钩子
-
useState
本身是一个函数,来自react包,参数和返回值,返回一个数组. 作用:状态钩子,为函数组件内提供状态
pages/useState/Index.js import React,{useState} from 'react' export default ()=>{ /** * 参数:接受一个初始值 * 返回值:返回一个数组,[val,setval] */ // console.log(useState(0)); const [count,setCount] = useState(0) const [food,setFood] = useState('') return ( <div> <h1>useState</h1> <div>你点击屏幕了:{count}次</div> <button onClick={()=>setCount(count+1)}>add</button> </div> ) }
-
useEffect
作用:useEffect用于处理组件中的effect,通常用于请求数据,事件处理,订阅等 相关操作 语法:他接收两个参数。参数一:进行的异步操作 参数二:是数组,用来给出Effect的 依赖项
类使用组件实现count的更新
import React, { Component } from 'react' export default class Effect extends Component { state = { count:0 } componentDidMount(){ document.title = `你点击屏幕了${this.state.count}次` } componentDidUpdate(){ document.title = `你点击屏幕了${this.state.count}次` } render() { return ( <div> <div>你点击屏幕了:{this.state.count}次</div> <button onClick={()=>this.add()}>add</button> </div> ) } add(){ this.setState({count:this.state.count+1}) } }
useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。 1).只有一个回调函数作为参数,相当于 componentDidMount componentDidUpdate 2).第二个参数是[],相当于componentDidMount 3).第二个参数是[count],相当于componentDidMount 和count变化,才执行 4).return:相当于componentWillUnmount
(1).只有一个回调函数作为参数,相当于 componentDidMount + componentDidUpdate
import React,{useEffect,useState} from 'react' export default ()=>{ const [count,setCount] = useState(0) // 参数一: 使用回调函数作为参数,相当于componentDidMount和componentDidUpdate useEffect(()=>{ document.title = `你点击屏幕了${count}次` }) return ( <div> <h1>useEffect</h1> <div>你点击屏幕了:{count}次</div> <button onClick={()=>setCount(count+1)}>add</button> </div> ) }
(2)第二个参数是[],相当于componentDidMount
import React,{useEffect,useState} from 'react' export default ()=>{ const [count, setCount] = useState(0) /** * 1.只有一个参数时,useEffect表示组件挂载完成和自减更新完成的钩子 * 2.第二个参数[],useEffect表示组件挂载完成componentDidMount * */ useEffect(()=>{ document.title = `你点击屏幕了${count}次` },[]) return ( <div> <div>你点击屏幕了:{count}次</div> <button onClick={()=>setCount(count+1)}>add</button> </div> ) }
(3)第二个参数是[count],相当于componentDidMount 和count变化,才执行
import React,{useEffect,useState} from 'react' export default ()=>{ const [count, setCount] = useState(0) const [name,setName] = useState('于增超') /** * 1.只有一个参数时,useEffect表示组件挂载完成和自减更新完成的钩子 * 2.第二个参数[],useEffect表示组件挂载完成componentDidMount * 3.第二个参数[count],useEffect表示组件挂载完成componentDidMount和count发生改变时,才执行 */ useEffect(()=>{ console.log(111); document.title = `你点击屏幕了${count}次` },[count]) return ( <div> <div>你点击屏幕了:{count}次</div> <button onClick={()=>setCount(count+1)}>add</button> <hr /> <div>{name}</div> <button onClick={()=>setName('Tom')}>李玉斌</button> </div> ) }
(4)return:相当于componentWillUnmount
import React,{useEffect,useState} from 'react' export default ()=>{ const [date,setDate] = useState(new Date()) useEffect(()=>{ let timer = setInterval(() => { setDate(new Date()) }, 1000); // return表示的是componentWillUnmount return ()=>{ console.log('clear'); clearInterval(timer) } },[]) return ( <div> <div>当前时间为:{date.toLocaleTimeString()}</div> </div> ) }
-
useReducer
作用: (1)useReducer() 提供了状态管理 (2)基本原理是通过用户在页面中发起 action, 从而通过reducer方法来改变state, 从而实现页面和状态的通信
语法
const [state, dispatch] = useReducer(reducer, initState);
import React,{useReducer} from 'react' // 初始值 const initialState = { count:0, } // 创建reducer const reducer = (state,action)=>{ switch (action.type) { case 'add': return { ...state, count:action.count+1 } case 'sub': return { ...state, count:action.count-1 } default: throw new Error('没有action的type',action.type) } } export default ()=>{ const [state,dispatch] = useReducer(reducer,initialState) // console.log(useReducer(reducer,initialState)); return ( <div> <div>{state.count}</div> <button onClick={()=>dispatch({type:'add',count:state.count})}>add</button> <button onClick={()=>dispatch({type:'sub',count:state.count})}>sub</button> </div> ) }
-
useContext
作用: 1.在组件之间共享状态, 2.可以解决react逐层通过props传递 3.她接受React.createContext()的返回结果作为参数
场景:在Hooks中,如果父组件传递数据给子组件,子组件没有使用,向下传递,子 组件的子组件进行使用,如果通过Props传递,可以使用,但是如果层级比较多,就会不方 便,那么可以子组件的子组件可以通过useContext进行接收数据。
Context.jsx
import react,{createContext,useState} from 'react' import Child from './Child' // 创建myContext export const myContext = createContext() console.log(myContext); export default ()=>{ const [name,setName] = useState('于增超') return ( <div className="alert alert-info"> <h1>useContext</h1> <myContext.Provider value={name}> <Child></Child> </myContext.Provider> </div> ) }
Child.jsx
import React from 'react' import Child1 from './Child1' export default ()=>{ return ( <div className="well"> <h1>子组件</h1> <Child1></Child1> </div> ) }
Child1.jsx
import React,{useContext} from 'react' import {myContext} from './Context' export default ()=>{ return ( <div className="alert alert-info"> <h1>子组件的子组件</h1> {useContext(myContext)} </div> ) }
-
自定义hook
构建自己的 Hooks 可以将组件逻辑提取到可重用的函数中。 当我们想要在两个 JavaScript 函数之间共享逻辑时,我们会将共享逻辑提取到第三个函数。 组件和 Hook 都是函数,所以这种办法也适用于它们! 自定义 Hook 是一个 JavaScript 函数,其名称以 ”use” 开头,可以调用其他 Hook。
Login.jsx
import React,{useState} from 'react' export default ()=>{ const [name,setName] = useState('') const [pass,setPass] = useState('') const login = ()=>{ console.log(name); console.log(pass); } return ( <div> <h1>登录页面</h1> <div>用户名 <input type="text" value={name} onChange={(e)=>setName(e.target.value)} /> </div> <div>密码 <input type="password" value={pass} onChange={(e)=>setPass(e.target.value)} /> </div> <div> <button onClick={()=>login()} >登录</button> </div> </div> ) }
自定义的hook
import React,{useState} from 'react' // 自定义hook const useInputVal = ()=>{ const [val,setVal] = useState() return { val: val, onChange:(e)=>setVal(e.target.value) } } export default ()=>{ // console.log(useInputVal());/ const {...name} = useInputVal() const {...pass} = useInputVal() const login = ()=>{ console.log(name); console.log(pass); } return ( <div> <h1>登录页面</h1> <div>用户名 <input type="text" {...name} /> </div> <div>密码 <input type="password" {...pass} /> </div> <div> <button onClick={()=>login()} >登录</button> </div> </div> ) }
-
hooks规则
1.只在顶层使用hook
2.只在react函数中调用hook,不要在普通javascript函数中调用hook