hooks的基本用法

在 React 16.8 之前,函数组件只能是无状态组件,也不能访问 react 生命周期。

hook 做为 react 新增特性,可以让我们在不编写 class 的情况下使用 state 以及其他的 react 特性。

使用函数组件也有以下几点好处:

  • 风格清爽,函数式编程风格,函数式组件、状态保存在运行环境、每个功能都包裹在函数中,整体风格更清爽,更优雅。
  • 代码量小
  • 可以使用函数组合,嵌套,实现功能更加强大的组件。
  • 组件不会被实例化,整体渲染性能得到提升。

常用的hooks有以下几种:

  • useState,useEffect,useRef,useContext
  • useSelector,useDispatch
  • 自定义hooks

 

1.useState(state,setState)

示例:点击按钮,使得按钮的文案由"点击前"变为“点击后”。

传统的写法:

import React, { Component } from "react";

export default class Button extends Component {
    constructor() {
        super();
        this.state = {
            buttonText: "点击前"
        };
    }
    handleClick() {
        this.setState({
            'buttonText': "点击后"
        });
    }
    render() {
        const { buttonText } = this.state;
        return <button onClick={() => this.handleClick()}>{buttonText}</button>;
    }
}

使用hooks的写法:函数组件不需要构造函数,可以通过调用 useState 来初始化 state

import React, { useState } from "react";

export default function Button() {
    const [buttonText,setButtonText] = useState("点击前");
    const handleClick = () => {
        setButtonText("点击后");
    }
    return <button onClick={handleClick}>{buttonText}</button>;
}

 

2.useEffect (componentDidMount,componentDidUpdate,componentWillUnmount)

useEffect 拥有两个参数,第一个参数作为回调函数会在浏览器布局和绘制完成后调用,因此它不会阻碍浏览器的渲染进程。
第二个参数是一个数组

  • 当数组存在并有值时,如果数组中的任何值发生更改,则每次渲染后都会触发回调。
  • 当它不存在时,每次渲染后都会触发回调。
  • 当它是一个空列表时,回调只会被触发一次,类似于 componentDidMount。

示例:新建一个定时器,每秒数量+1

传统的写法:

import React, { Component } from 'react';
class Count extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 1,
        }
    }
    componentDidMount() {
        // 新建一个定时器实现+1操作
        this.timer = setInterval(() => {
            this.setState({
                count: this.state.count - 0 + 1
            })
        }, 1000);
    }
    componentWillUnmount() {
        // 组件销毁时清除定时器,否则会造成内存泄漏
        clearInterval(this.timer)
    }
    render() {
        return <div>
            {this.state.count}
        </div>
    }
}
export default Count;

hooks的写法:

import React, { useState, useEffect } from 'react';

const Count = (props) => {
    const [count, setCount] = useState(0);

    useEffect(() => {
        let timer = setInterval(() => {
            setCount(count + 1)
        }, 1000);
        // 当在 useEffect 的回调函数中返回一个函数时,这个函数会在组件卸载前被调用
        return () => clearInterval(timer)
        // count发生变化时再次执行
    }, [count]);

    return <div>
        {count}
    </div>
}
export default Count;

 

3.useRef

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。

示例:获取某个元素

传统写法:

import React, { Component } from 'react'

export default class Test extends Component {
    componentDidMount() {
        console.log(this.refs.box)
    }
    render() {
        return (
            <div ref="box">
                this is a box
            </div>
        )
    }
}

hooks写法:

import React, { useRef, useEffect } from "react";

export default function Test() {
    // 初始化一个useRef
    const box = useRef(null);

    useEffect(() => {
        // 通过.current获取
        console.log(box.current)
    }, [])

    return (
        <div ref={box}>this is a box</div>
    );
}

 

4.useContext

接收一个 context 对象,并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。

示例:父组件传值“Text”给子组件

传统方式:

//父组件
<Child Text="text" />

//子组件
export default class Child extends PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            'Text': props.CouponChannelID,
        };
    }
}

hooks方式: 


//父组件
import React from "react";

export const TextContext = React.createContext({});

<TextContext.Provider value={{
    text: "this is a text"
}}>
<Child></Child>
</TextContext.Provider>


//子组件接收

import React, { useContext } from "react";

import { TextContext } from './parent';

export default function MemberPop() {
    const { text } = useContext(TextContext);
}

 

使用useSelector useDispatch 替代connect

React Redux 现在提供了一系列 hook APIs 作为现在connect()高阶组件的替代品。这些 APIs 允许你,在不使用connect()包裹组件的情况下,订阅 Redux 的 store,和分发(dispatch) actions。

1.useSelector  从redux的store对象中提取数据

2.useDispatch 返回Redux store中对dispatch函数的引用

传统写法:

import React, { PureComponent, Fragment } from "react";
import { connect } from "react-redux";
import actions from "@/store/actions";

@connect(
    state => state.getData,
    actions
)
export default class BackTopWrap extends PureComponent {
    componentDidMount() {
        const {
            getShowAction,
        } = this.props;
        getShowAction();
    }
    render() {
        const { show } = this.props;
        return (
           <div className="backTop" style={{ "display": show ? "block" : "none" }}>                 
        );
    }
}

hooks写法: 

import React, { Fragment, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { getShowAction} from '@/store/actions';

export default function OpenedPage() {
    const { show } = useSelector(state => state.getData);
    const dispatch = useDispatch();

    useEffect(() => {
        getShowAction(dispatch);
    }, [])

    return (
       <div className="backTop" style={{ "display": show ? "block" : "none" }}>                 
    );
}

 

自定义hooks:

自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook。

示例:封装一个组件,实现鼠标滑过显示鼠标所在位置

传统方式:定义一个高阶组件,使用时将组件作为参数传入高阶组件

/**
 * 定义一个高阶组件
 * 返回鼠标所在位置
 */

import React from 'react'
export default (Component) => {
    return class WrappedComponent extends React.Component {
        constructor(props) {
            super(props)
            this.state = {
                positionX: 0,
                positionY: 0
            }
        }
        componentDidMount() {
            document.addEventListener('mousemove', (e) => {
                this.setState({
                    positionX: e.clientX,
                    positionY: e.clientY
                })
            }) // 在这里我们更新鼠标的位置,并存储在state中去,然后通过props传递给被传入的组件
        }
        render() {
            return (
                <Component {...this.props} {...this.state} {...{ 'x': 1 }} />
                //props:这里返回的是WrappedComponent这个组件,所以本应该传递给Component组件的props,我们应该通过WrappedComponent传递下去
                //state: WrappedComponent可以操作自己的状态,我们可以将这些状态通过props的方式传递给Component组件
            )
        }

    }
}
/**
 * 使用时将组件作为参数传入高阶组件
 */
import React from 'react';
import mousePositionHoc from './hoc';
class MousePoint extends React.Component {
    constructor(props) {
        super(props)
    }
    render() {
        return (
            <div>
                <span>x:{this.props.positionX}</span>
                <span>y:{this.props.positionY}</span>
            </div>
        )
    }
}
export default mousePositionHoc(MousePoint)

hooks:自定义一个hooks,使用时直接引入

/**
 * 自定义一个hooks
 * 返回鼠标所在位置
 */
import React, { useState, useEffect } from 'react'

const useMousePosition = () => {
    const [position, setPosition] = useState({ x: 0, y: 0 })
    useEffect(() => {
        const updateMouse = (e) => {
            setPosition({ x: e.clientX, y: e.clientY })
        }
        document.addEventListener('mousemove', updateMouse)
    }, [])
    return position
}

export default useMousePosition


//使用时引入自定义hooks
import React from 'react'
import useMousePosition from './hooks'

export default function App() {
    const position = useMousePosition()
    return (
        <div>
            <div>x: {position.x}</div>
            <div>y: {position.y}</div>
        </div>
    )
}
  • 33
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Composition API 是 Vue 3 中引入的新特性,它通过一种更灵活的方式来组织和重用组件逻辑。下面是 Composition API 的基本使用方法和常见的 Hooks: 1. reactive:用于将普通的数据转换为响应式数据。可以使用 reactive 函数将一个普通对象转换成响应式对象,这样当响应式对象的属性发生变化时,相关的视图会自动更新。 ```javascript import { reactive } from "vue"; const state = reactive({ count: 0, }); console.log(state.count); // 输出 0 state.count++; // 修改 count 的值 console.log(state.count); // 输出 1,视图自动更新 ``` 2. computed:用于创建计算属性。computed 函数接收一个 getter 函数,返回一个计算属性对象。计算属性的值会根据其依赖的响应式数据动态计算,并且只有在依赖发生变化时才会重新计算。 ```javascript import { reactive, computed } from "vue"; const state = reactive({ count: 0, }); const doubleCount = computed(() => { return state.count * 2; }); console.log(doubleCount.value); // 输出 0 state.count++; // 修改 count 的值 console.log(doubleCount.value); // 输出 2,自动重新计算 ``` 3. watch:用于观察响应式数据的变化。watch 函数接收两个参数:要观察的响应式数据和回调函数。当响应式数据发生变化时,回调函数会被调用。 ```javascript import { reactive, watch } from "vue"; const state = reactive({ count: 0, }); watch( () => state.count, (newCount, oldCount) => { console.log(`count 变化了:${oldCount} => ${newCount}`); } ); state.count++; // 输出 "count 变化了:0 => 1" ``` 这些是 Composition API 中常见的 Hooks。除了上述的 Hooks,还有其他一些常用的 Hooks,如:ref、toRefs、onMounted 等。你可以根据具体的需求去使用它们。希望能对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值