react hook有10个:1、usestate,用于设置和改变state;2、usememo,用于控制组件更新条件;3、usecontext,用于组件传值;4、usedebugvalue,显示自定义标签;5、usecallback等等。
本教程操作环境:windows7系统、react17.0.1版、dell g3电脑。
react hook是什么?react官网是这么介绍的: hook 是 react 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 react 特性。
完全可选的你无需重写任何已有代码就可以在一些组件中尝试 hook。但是如果你不想,你不必现在就去学习或使用 hook。
100% 向后兼容的hook 不包含任何破坏性改动。
现在可用hook 已发布于 v16.8.0。
没有计划从 react 中移除 class你可以在本页底部的章节读到更多关于 hook 的渐进策略。
hook 不会影响你对 react 概念的理解恰恰相反,hook 为已知的 react 概念提供了更直接的 api:props, state,context,refs 以及生命周期。稍后我们将看到,hook 还提供了一种更强大的方式来组合他们。
如果对react还不够了解建议先看下react官方文档,写写demo再来看文章,因为有的react基础的东西我就一笔带过不细说。
react 官方文档 https://zh-hans.reactjs.org/docs/hooks-state.html
react提供的hookhook用途
usestate 设置和改变state,代替原来的state和setstate
useeffect 代替原来的生命周期,componentdidmount,componentdidupdate 和 componentwillunmount 的合并版
uselayouteffect 与 useeffect 作用相同,但它会同步调用 effect
usememo 控制组件更新条件,可根据状态变化控制方法执行、优化传值
usecallback usememo优化传值,usecallback优化传的方法,是否更新
useref 跟以前的ref,一样,只是更简洁了
usecontext 上下文爷孙及更深组件传值
usereducer 代替原来redux里的reducer,配合usecontext一起使用
usedebugvalue 在 react 开发者工具中显示自定义 hook 的标签,调试使用。
useimperativehandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。
1.usestate
import react from 'react';import './app.css';//通常的class写法,改变状态class app extends react.component { constructor(props){ super(props) this.state = { hook:'react hook 是真的好用啊' } } changehook = () => { this.setstate({ hook:'我改变了react hook 的值' }) } render () { const { hook } = this.state return( <header classname="app-header"> {hook} <button onclick={this.changehook}> 改变hook </button> </header> ) }}export {app}//函数式写法,改变状态function app() {//创建了一个叫hook的变量,sethook方法可以改变这个变量,初始值为‘react hook 是真的好用啊’ const [hook, sethook] = usestate("react hook 是真的好用啊"); return ( <header classname="app-header"> {hook}{/**这里的变量和方法也是可以直接使用的 */} <button onclick={() => sethook("我改变了react hook 的值")}> 改变hook </button> </header> );}export {app}//箭头函数的函数写法,改变状态export const app = props => { const [hook, sethook] = usestate("react hook 是真的好用啊"); return ( <header classname="app-header"> {hook} <button onclick={() => sethook("我改变了react hook 的值")}> 改变hook </button> </header> );};
使用方法备注在上面的demo中
看完上面usestate的对比使用,一个小的demo结构更清晰,代码更简洁,更像写js代码,运用到项目中,那岂不是美滋滋。
2.useeffect & uselayouteffect
useeffect代替原来的生命周期,componentdidmount,componentdidupdate 和 componentwillunmount 的合并版
useeffect( ()=>{ return ()=>{ } } , [ ])
第一个参数,是函数,默认第一次渲染和更新时都会触发,默认自带一个return ,return一个函数表示可以再销毁之前可以处理些事情第二个参数,数组【】,空的时候表示只执行一次,更新时不触发,里面的参数是什么,当参数变化时才会执行useeffect
useeffect可以多次使用,按照先后顺序执行
uselayouteffect强制useeffect的执行为同步,并且先执行uselayouteffect内部的函数import react, { usestate, useeffect, uselayouteffect } from 'react';//箭头函数的写法,改变状态const useeffect = (props) => { //创建了一个叫hook的变量,sethook方法可以改变这个变量,初始值为‘react hook 是真的好用啊’ const [ hook, sethook ] = usestate('react hook 是真的好用啊'); const [ name ] = usestate('baby张'); return ( <header classname="useeffect-header"> <h3>useeffect</h3> <child hook={hook} name={name} /> {/**上面的变量和下面方法也是可以直接使用的 */} <button onclick={() => sethook('我改变了react hook 的值' + new date().gettime())}>改变hook</button> </header> );};const child = (props) => { const [ newhook, setnewhook ] = usestate(props.hook); //这样写可以代替以前的componentdidmount,第二个参数为空数组,表示该useeffect只执行一次 useeffect(() => { console.log('first componentdidmount'); }, []); //第二个参数,数组里是hook,当hook变化时,useeffect会触发,当hook变化时,先销毁再执行第一个函数。 useeffect( () => { setnewhook(props.hook + '222222222'); console.log('useeffect'); return () => { console.log('componentwillunmount '); }; }, [ props.hook ] ); //uselayouteffect 强制useeffect的执行为同步,并且先执行uselayouteffect内部的函数 uselayouteffect( () => { console.log('uselayouteffect'); return () => { console.log('uselayouteffect componentwillunmount'); }; }, [ props.hook ] ); return ( <div> <p>{props.name}</p> {newhook} </div> );};export default useeffect;
3.usememo & usecallback
他们都可以用来优化子组件的渲染问题,或者监听子组件状态变化来处理事件,这一点在以前是很难做到的,因为shouldcomponentupdate 里能监听到是否变化,但没法控制其他的外部方法,只能返回true和false,而componentdidupdate只能在更新后执行,所以想在渲染之前做些事情就不好搞了。
usecallback目前还不能用
import react, { usestate, usememo } from 'react';const child = ({ age, name, children }) => { //在不用usememo做处理的时候,只要父组件状态改变了,子组件都会渲染一次,用了usememo可以监听某个状态name,当name变化时候执行usememo里第一个函数 console.log(age, name, children, '11111111'); function namechange() { console.log(age, name, children, '22222222'); return name + 'change'; } {/** react 官网虽说usecallback与usememo的功能差不多,但不知道版本问题还怎么回是,这个方法目前还不能用 const memoizedcallback = usecallback( () => { console.log('usecallback') }, [name], ); console.log(memoizedcallback,'memoizedcallback') */} //usememo有两个参数,和useeffect一样,第一个参数是函数,第二个参数是个数组,用来监听某个状态不变化 const changedname = usememo(() => namechange(), [ name ]); return ( <div style={{ border: '1px solid' }}> <p>children:{children}</p> <p>name:{name}</p> <p>changed:{changedname}</p> <p>age:{age}</p> </div> );};const usememo = () => { //usestate 设置名字和年龄,并用2两个按钮改变他们,传给child组件 const [ name, setname ] = usestate('baby张'); const [ age, setage ] = usestate(18); return ( <div> <button onclick={() => { setname('baby张' + new date().gettime()); }} > 改名字 </button> <button onclick={() => { setage('年龄' + new date().gettime()); }} > 改年龄 </button> <p> usememo {name}:{age} </p> <child age={age} name={name}> {name}的children </child> </div> );};export default usememo;
4.useref
ref跟之前差不多,useref创建–绑定–使用,三步走,详细看代码以及备注
import react, { usestate, useref } from 'react';const useref = () => { //这里usestate绑定个input,关联一个状态name const [ name, setname ] = usestate('baby张'); const refvalue = useref(null);// 先创建一个空的useref function addref() { refvalue.current.value = name; //点击按钮时候给这个ref赋值 // refvalue.current = name //这样写时,即使ref没有绑定在dom上,值依然会存在创建的ref上,并且可以使用它 console.log(refvalue.current.value); } return ( <div> <input defaultvalue={name} onchange={(e) => { setname(e.target.value); }} /> <button onclick={addref}>给下面插入名字</button> <p>给我个useref名字:</p> <input ref={refvalue} /> </div> );};export default useref;
5.usecontext
之前使用过context的小伙伴一看就懂,usecontext的话跟之前的context基本用法差不多,代码内有详细注释说明,创建,传值,使用
import react, { usestate, usecontext, createcontext } from 'react';const contextname = createcontext();//这里为了方便写博客,爷爷孙子组件都写在一个文件里,正常需要在爷爷组件和孙子组件挨个引入创建的contextconst usecontext = () => { //这里usestate创建一个状态,并按钮控制变化 const [ name, setname ] = usestate('baby张'); return ( <div> <h3>usecontext 爷爷</h3> <button onclick={() => { setname('baby张' + new date().gettime()); }} > 改变名字 </button> {/**这里跟context用法一样,需要provider向子组件传递value值,value不一定是一个参数 */}} <contextname.provider value={{ name: name, age: 18 }}> {/**需要用到变量的子组件一定要写在provider中间,才能实现共享 */} <child /> </contextname.provider> </div> );};const child = () => { //创建一个儿子组件,里面引入孙子组件 return ( <div style={{ border: '1px solid' }}> child 儿子 <childchild /> </div> );};const childchild = () => { //创建孙子组件,接受爷爷组件的状态,用usecontext,获取到爷爷组件创建的contextname的value值 let childname = usecontext(contextname); return ( <div style={{ border: '1px solid' }}> childchild 孙子 <p> {childname.name}:{childname.age} </p> </div> );};export default usecontext;
6.usereducer
这里的usereducer会返回state和dispatch,通过context传递到子组件,然后直接调用state或者触发reducer,我们常用usereducer 与usecontext createcontext一起用,模拟reudx的传值和重新赋值操作。
import react, { usestate, usereducer, usecontext, createcontext } from 'react';//初始化stroe的类型、初始化值、创建reducerconst add_counter = 'add_counter';const initreducer = { count: 0};//正常的reducer编写function reducer(state, action) { switch (action.type) { case add_counter: return { ...state, count: state.count + 1 }; default: return state; }}const countcontext = createcontext();//上面这一段,初始化state和reducer创建context,可以单独写一个文件,这里为了方便理解,放一个文件里写了const usereducer = () => { const [ name, setname ] = usestate('baby张'); //父组件里使用usereducer,第一个参数是reducer函数,第二个参数是state,返回的是state和dispash const [ state, dispatch ] = usereducer(reducer, initreducer); return ( <div> usereducer {/* 在这里通过context,讲reducer和state传递给子组件*/} <countcontext.provider value={{ state, dispatch, name, setname }}> <child /> </countcontext.provider> </div> );};const child = () => { //跟正常的接受context一样,接受父组件的值,通过事件等方式触发reducer,实现redux效果 const { state, dispatch, name, setname } = usecontext(countcontext); function handleclick(count) { dispatch({ type: add_counter, count: 17 }); setname(count % 2 == 0 ? 'babybrother' : 'baby张'); } return ( <div> <p> {name}今年{state.count}岁 </p> <button onclick={() => handleclick(state.count)}>长大了</button> </div> );};export default usereducer;
【相关推荐:redis视频教程】
以上就是react hook有哪些的详细内容。