React (hooks)

hooks

  1. 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():共享状态钩子
  1. 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>
    )
}
  1. 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>
    )
}
  1. 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>
    )
}
  1. 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>
    )
}
  1. 自定义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>
    )
}
  1. hooks规则

1.只在顶层使用hook

2.只在react函数中调用hook,不要在普通javascript函数中调用hook

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值