likes
comments
collection
share

看看react中的hooks都有点啥

作者站长头像
站长
· 阅读数 22

useState

用于在函数式组件中添加状态管理

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  function handleIncrement() {
    setCount(oldCount => oldCount + 1);
  }

  function handleDecrement() {
    setCount(oldCount => oldCount - 1);
  }

  return (
    <div>
      <h2>Counter: {count}</h2>
      <button onClick={handleIncrement}>Increment</button>
      <button onClick={handleDecrement}>Decrement</button>
    </div>
  );
}

useEffect

用于在函数式组件中添加副作用,比如发送网络请求,订阅事件等

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

function fetchData() {
  // 发送网络请求获取数据
  return fetch('https://someapi.com/data')
    .then(response => response.json())
    .then(data => data);
}

function DataDisplay() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetchData().then(data => setData(data));
  }, []);

  if (data === null) {
    return <div>Loading...</div>;
  }

  return <div>{JSON.stringify(data)}</div>;
}

useContext

用于在函数式组件中使用全局数据

import React, { useContext } from 'react';

const ThemeContext = React.createContext('light');

function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return <button style={{ background: theme }}>I am styled by theme context!</button>;
}
import React, { useContext } from 'react'
import UserContext from './context';


function Demo() {
// 如果React.createContext没有指定默认值,也可以在对应子组件上套上UserContext.Provider来指定值
    return (
        // <UserContext.Provider value={{ name: '张三' }}>
            <Child />
        // </UserContext.Provider>
    )
}



function Child() {
    const UserContext = React.createContext( { name: '张三' });
    const user = useContext(UserContext);
    return (
        <div>
            <p>{`name: ${user.name}`}</p>
        </div>
    )
}

export default Demo;

**

useReducer

用于在函数式组件中使用复杂的状态逻辑,可以用于替代 useState

import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  // 第一个参数reducer是一个函数,第二个参数initialState是定义state初始值
  const [state, dispatch] = useReducer(reducer, initialState);

  function handleIncrement() {
    dispatch({ type: 'increment' });
  }

  function handleDecrement() {
    dispatch({ type: 'decrement' });
  }

  return (
    <div>
      <h2>Counter: {state.count}</h2>
      <button onClick={handleIncrement}>Increment</button>
      <button onClick={handleDecrement}>Decrement</button>
    </div>
  );
}

useMemo

用于缓存计算结果,当计算结果不变时,可以避免重复计算

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

function fibonacci(n) {
  if (n <= 1) {
    return 1;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
}

function MyComponent({ number }) {
  const result = useMemo(() => fibonacci(number), [number]);

  return <div>{result}</div>;
}

在这个示例中,我们定义了一个计算斐波那契数列的函数 fibonacci,然后使用 useMemo 缓存计算结果,只有当 number 发生变化时,才会重新计算。这样可以提高组件的性能。

useCallback

用于缓存函数,减少函数的重新创建

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

function MyComponent() {
  const [count, setCount] = useState(0);

  const handleIncrement = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
}
import { useState, useCallback } from 'react'

function Demo() {
    const [count1, setCount1] = useState(0);
    const [count2, setCount2] = useState(0);
    const funcHang = useCallback(function() {
        console.log("function run:", count1, count2);
    }, [count1]);

    return (
        <div>
            <h2>params: { count1 } { count2 }</h2>
            <button onClick={ funcHang }>触发</button>
            <button onClick={ e => { setCount1(pre => pre + 1);} }>update Count1</button>
            <button onClick={ e => { setCount2(pre => pre + 1);} }>update Count2</button>
        </div>
    )
}

export default Demo;

在这个示例中,我们使用 useCallback 缓存了一个叫做 handleIncrement 的函数,这个函数只有在 count 发生改变时才会重新创建。这样可以减少函数的重新创建,提高组件性能。

useRef

创建一个可变的 ref 对象,在 React 更新视图时不会重新渲染,可以用于保存和读取 DOM 元素、记录变量值等

import React, { useRef } from 'react';

function TextInput() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={handleClick}>Focus</button>
    </div>
  );
}
import { useRef } from 'react'

function Demo() {
    const inputRef = useRef();

    const handleFocus = () => {
        // document.getElementById('my-input').focus();
        inputRef.current.value = 'focus';
        inputRef.current.focus();
    }

    const handleBlur = () => {
        // document.getElementById('my-input').blur();
        inputRef.current.value = 'blur';
        inputRef.current.blur();
    }

    return (
        <div>
            <input ref={inputRef} id="my-input" />
            <button onClick={handleFocus}>focus</button>
            <button onClick={handleBlur}>blur</button>
        </div>
    )
}

export default Demo;

在这个示例中,我们使用 useRef 创建了一个 inputRef 对象,它可以用来保存 input 元素的引用。然后我们又定义了一个 handleClick 函数,当点击按钮时,调用 inputRef.current.focus() 来使 input 元素获得焦点。

useLocation

useLocationReact Router提供的一个Hooks,用于在React组件中获取当前页面URL地址的信息,包括pathnamesearchhash,从而可以在页面跳转、渲染和传递参数等方面进行更精细的控制。useLocation的实现基于window.location对象,所以在浏览器上运行的React应用程序才能使用它。在使用useLocation时,需要先通过react-router-dom引入它,然后在函数组件中通过调用useLocation就可以获取到当前页面的URL地址信息。

import { useLocation } from 'react-router-dom'

const GeekLayout = () => {
  const location = useLocation()
  // 这里是当前浏览器上的路径地址
  const selectedKey = location.pathname
   return ( <div></div> )
}

forwardRef

forwardRef是一种高阶组件,用于将ref向下传递到子组件中。具体用法如下:

import React, { forwardRef, useRef } from 'react';

const Input = forwardRef((props, ref) => {
  return <input type="text" ref={ref} {...props} />;
});

function App() {
  const inputRef = useRef(null);

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <Input ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

在上面的示例中,我们创建了一个名为Input的组件,并使用forwardRef将其转发给子组件,并将ref传递给子组件的input元素。在App组件中,我们创建了一个ref,并将其传递给Input组件。然后我们在App组件中创建了一个按钮,并在点击时让input元素获得焦点,这是通过调用inputRef.current.focus()实现的。这个功能是通过Props传递实现的,但是直接把ref传递给Input的话,Input组件是无法获得ref的,这时就可以使用forwardRef传递ref。

需要注意:

  • forwardRef只能转发refs而不能转发其他props
  • forwardRef要使用回调形式传递ref
转载自:https://juejin.cn/post/7226925675050483767
评论
请登录