初识react-hooks

Jiafeng

分类: React 371 0

hooks使命

  • 逻辑与UI组件分离
    • React 官方推荐在开发中将逻辑部分与视图部分结耦,便于定位问题和职责清晰
  • 函数组件拥有state
    • 在函数组件中如果要实现类似拥有state的状态,必须要将组件转成class组件
  • 逻辑组件复用

hooks官方api

  • useState

    • 作用:函数组件中的state方法,用于定义响应式数据

    • 使用:name:变量,setName:改变变量name的方法,通过setName方法修改name

    • import { useState } from 'react';
      const  [name, setName] = useState(0);
  • useEffect

    • 作用:函数组件处理副作用的方法,如:异步请求、订阅原生的dom实事件、setTimeoutd等,第一次渲染完成后每次更新渲染会自动执行该函数

    • 使用:有2个参数,分别为function、list,返回参数 function

    • 注意:

    • 不接受第二个参数,第一次渲染完成之后和每次更新渲染后执行

    • 接收第二个参数list,只有在list发生改变时执行。传入的为空数组[] ,只执行一次

    • 若绑定一些DOM事件需清除

    • import React,{useEffect} from 'react';
      // 我们可以把useEffect 看做componentDidmount、componentDidUpdate、componntWillUnmount
      const HooksTest = () => {
      const [count, setCount] = useState(0);
      // useEffect可以让你在第一个参数的函数中执行副作用操作,就是请求数据,dom操作之类的
      // useEffect返回一个函数,函数里表示要清除的副作用,例如清除定时器,返回的函数会在卸载组件时执行
      useEffect(()=>{
          document.title = You clicked ${count} times;
          return ()=>{
              clearInterval(timer)
          }
      })
      /*
        useEffect的第二个参数,通过在数组中传递值,例如只有count变化时才调用Effect,达到
        不用每次渲染后都执行清理或执行effect导致的性能问题
      */
      useEffect(()=>{
       document.title = You clicked ${count} times;
      },[count])
      /*
      如果想执行只运行一次的effect(仅在组件挂载和卸载时执行),可以传递一个空数组,
      告诉React你的Effect不依赖与props或state中任何值
      */
      useEffect(()=>{
       document.title = You clicked ${count} times;
      },[])
      /* 
        可以使用多个Effect,将不相关的逻辑分离到不同的effect中
      */
      useEffect(()=>{
         axios.get('login')
      },[])
      return(
           <div>
              <p>You clicked {count} times</p>
              <button onClick={() => setCount(count + 1)}>
                  Click me
              </button>
           </div>
      )
      }
  • useRef

    • 作用:获取DOM对象,保存数据

    • // 获取dom对象
      import { useRef } from 'react';
      const input:any = useRef(null)
      useEffect(()=>{
      input.current.focus()
      }, [])
      return (
      <>
          <input type="text" ref={input}/>
      </>
      )
      // 存放变量
      const intervalRef=useRef()
      useEffect(()=>{
      intervalRef.current=setInterVal(()=>{})
      return ()=>{
          clearInterval(intervalRef.current)
      }
      })
  • useMemo

    • 作用:随组件中的状态更新时才调用,防止渲染次数过多导致内存溢出,优化代码逻辑优化性能
    • 使用:
    • 接收function作为参数
    • 接收第二个参数list,只有在list发生改变时执行
    • 返回的是一个值。返回值可以是任何,函数、对象等都可以
  • useContext

    • 作用:可以帮助我们跨越组件层级直接传递变量,实现数据共享

    • 使用:接受一个context对象(React.createContext的返回值)并返回该context的当前值

    • // helpers.tsx
      export const defaultSorted = [{ dataField: 'id', order: 'asc' }];
      export const sizePerPageList = [
      { text: '5', value: 5 },
      { text: '10', value: 10 },
      { text: '20', value: 20 },
      ];
      export const initialFilter = {
      pageNumber: 1,
      pageSize: 10,
      };
      // ui-context.tsx 创建一个上下文管理组件
      import React, { createContext, useContext, useState, useCallback } from 'react';
      import { initialFilter } from './helpers';
      const UiContext = createContext<any>(null);
      export function useUIContext() {
      return useContext(UiContext);
      }
      export const UIProvider = ({ UIEvents, children }: any) => {
      const [queryParams, setQueryParamsBase] = useState(initialFilter);
      const value = {
          queryParams,
          setQueryParamsBase,
          funLog: UIEvents.funLog,
          change: () => {
              setQueryParamsBase({
                  pageNumber: 2,
                  pageSize: 10,
              })
          }
      }
      return (
          <UiContext.Provider value={value}>{children}</UiContext.Provider>
      )
      }
      // index.tsx
      import { UIProvider } from '../ui-context';
      import { Child } from './child'
      const ContextDemo = () => {
      const UIEvents = {
          funLog: () => {
              console.log('测试')
          }
      }
      return (
          <UIProvider UIEvents={UIEvents}>
              <Child />
          </UIProvider>
      )
      }
      export default ContextDemo
      // child.tsx
      import { useUIContext } from '../ui-context';
      import React, { useMemo } from 'react';
      import { Button } from 'antd';
      export const Child = () => {
      const UIContext = useUIContext();
      const UIProps = useMemo(() => {
          return {
              queryParams: UIContext.queryParams,
              setQueryParamsBase: UIContext.setQueryParamsBase,
              funLog: UIContext.funLog,
              change: UIContext.change
          };
      }, [UIContext]);
      
      const handleClick = () => {
          UIProps.funLog()
      }
      return (
          <>
              {
                  Object.keys(UIProps.queryParams).map((item, index) => <p key={index}>{item}:{UIProps.queryParams[item]}</p>)
              }
              <Button type="primary" onClick={handleClick}>测试</Button>
              <Button type="primary" onClick={UIProps.change}>change</Button>
          </>
      )
      } 
  • useImperativeHandle

    • 作用:可以让你在使用ref时自定义暴露给父组件的实例值,useImperativeHandle 应当与forwardRef 一起使用,这样可以父组件可以调用子组件的方法

    • // 父组件
      function Father () {
      const modelRef = useRef(null);
      /* 确定 */
      function sureBtn() {
        // 调用子组件的方法
      modelRef.current.model();
      }
      return (
       <>
       <Button onClick={sureBtn}>确定</Button>
       <Children ref={modelRef}></Children>
       </>
      )
      }
      // 子组件
      const Children = React.forwardRef((props,ref)=>{
      const [visible, setVisible] = useState(false);
      useImperativeHandle(ref, () => ({
        model: () => {
          setVisible(true);
        },
      }));
      })
  • 扩展资料

  • 2人 Love
  • 1人 Haha
  • 0人 Wow
  • 0人 Sad
  • 0人 Angry
ReactHooks

作者简介: Jiafeng

共 0 条评论关于 “初识react-hooks”

Loading...