”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > React Hooks 示例

React Hooks 示例

发布于2024-11-08
浏览:174

React Hooks with Example

Introduction: Embracing the Power of React Hooks

Hey there, fellow UI developer! Are you ready to dive into the exciting world of React Hooks? If you've been working with React for a while, you might remember the days when class components were the go-to for managing state and side effects. But times have changed, and React Hooks have revolutionized the way we build components.

In this friendly guide, we'll explore 10 essential React Hooks, complete with example tutorials to help you understand and implement them in your projects. Whether you're new to Hooks or looking to deepen your knowledge, this post has got you covered. So, grab your favorite beverage, get comfortable, and let's embark on this React Hooks adventure together!

1. useState: Managing State with Ease

Let's kick things off with the most commonly used Hook: useState. This little gem allows you to add state to your functional components without the need for classes.

How it works

The useState Hook returns an array with two elements: the current state value and a function to update it. Here's a simple example:

import React, { useState } from 'react';

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

  return (
    

You clicked {count} times

); }

In this example, we're creating a counter that increases every time the button is clicked. The useState Hook initializes our count to 0, and we use the setCount function to update it.

When to use useState

  • When you need to manage local state in a functional component
  • For simple data types like numbers, strings, or booleans
  • When you want to avoid the complexity of class components for basic state management

2. useEffect: Handling Side Effects

Next up is useEffect, the Hook that lets you perform side effects in your components. It's like componentDidMount, componentDidUpdate, and componentWillUnmount all rolled into one!

How it works

useEffect takes two arguments: a function to run after render, and an optional array of dependencies. Here's an example:

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

function WindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);

    // Cleanup function
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []); // Empty dependency array means this effect runs once on mount

  return 
Window width: {width}px
; }

In this example, we're using useEffect to add an event listener for window resizing. The cleanup function removes the listener when the component unmounts.

When to use useEffect

  • For data fetching
  • Setting up subscriptions or event listeners
  • Manually changing the DOM
  • Logging or any other side effects that don't directly impact the render

3. useContext: Consuming Context with Ease

The useContext Hook provides a way to consume context in functional components without the need for render props or higher-order components.

How it works

First, you create a context using React.createContext(), then use the useContext Hook to consume it:

import React, { useContext } from 'react';

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

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

function App() {
  return (
    
      
    
  );
}

In this example, ThemedButton uses the useContext Hook to access the current theme value from ThemeContext.

When to use useContext

  • When you need to share data that can be considered "global" for a tree of React components
  • To avoid prop drilling (passing props through multiple levels of components)
  • For theming, user authentication, or any other application-wide data

4. useReducer: Managing Complex State Logic

When useState isn't enough, useReducer comes to the rescue. It's particularly useful for managing more complex state logic.

How it works

useReducer takes a reducer function and an initial state, and returns the current state paired with a dispatch method:

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() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    
      Count: {state.count}
      
      
    >
  );
}

In this example, we're using useReducer to manage a counter with increment and decrement actions.

When to use useReducer

  • When you have complex state logic that involves multiple sub-values
  • When the next state depends on the previous one
  • When you want to optimize performance for components that trigger deep updates

5. useCallback: Optimizing Performance

The useCallback Hook can help you optimize the performance of your components by memoizing callback functions.

How it works

useCallback returns a memoized version of the callback that only changes if one of the dependencies has changed:

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

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

  const increment = useCallback(() => {
    setCount(c => c   1);
  }, []);

  return (
    

Count: {count}

); } function ChildComponent({ onIncrement }) { console.log('ChildComponent rendered'); return ; }

In this example, the increment function is memoized with useCallback, preventing unnecessary re-renders of ChildComponent.

When to use useCallback

  • When passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders
  • In combination with useMemo for creating memoized callbacks

6. useMemo: Memoizing Expensive Computations

Similar to useCallback, useMemo is used for optimization, but it memoizes the result of a computation.

How it works

useMemo takes a function and an array of dependencies, and only recomputes the memoized value when one of the dependencies has changed:

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

function ExpensiveComponent({ list }) {
  const [filter, setFilter] = useState('');

  const filteredList = useMemo(() => {
    console.log('Filtering list...');
    return list.filter(item => item.toLowerCase().includes(filter.toLowerCase()));
  }, [list, filter]);

  return (
    
setFilter(e.target.value)} placeholder="Filter list" />
    {filteredList.map(item => (
  • {item}
  • ))}
); }

In this example, we're using useMemo to memoize the filtered list, preventing unnecessary recalculations on every render.

When to use useMemo

  • For expensive calculations that don't need to be re-run on every render
  • When you want to avoid re-rendering child components unnecessarily
  • For referential equality checks in other Hooks' dependency arrays

7. useRef: Accessing DOM Elements and Storing Mutable Values

The useRef Hook provides a way to create a mutable reference that persists across re-renders.

How it works

useRef returns a mutable ref object whose .current property is initialized to the passed argument:

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

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

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return ;
}

In this example, we're using useRef to get a reference to the input element and focus it when the component mounts.

When to use useRef

  • To access DOM elements directly
  • For storing mutable values that don't cause re-renders when updated
  • For keeping track of previous values in functional components

8. useImperativeHandle: Customizing Instance Value

useImperativeHandle customizes the instance value that is exposed to parent components when using ref.

How it works

useImperativeHandle should be used with forwardRef:

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

const FancyInput = forwardRef((props, ref) => {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
    getValue: () => {
      return inputRef.current.value;
    }
  }));

  return ;
});

function Parent() {
  const fancyInputRef = useRef();

  const handleClick = () => {
    fancyInputRef.current.focus();
    console.log(fancyInputRef.current.getValue());
  };

  return (
    
); }

In this example, we're using useImperativeHandle to customize what instance value is exposed to the parent component.

When to use useImperativeHandle

  • When you want to customize the exposed instance value of a forwardRef component
  • To limit the exposed functionality of a child component to its parent

9. useLayoutEffect: Synchronous Effect Hook

useLayoutEffect is similar to useEffect, but it fires synchronously after all DOM mutations.

How it works

The signature is identical to useEffect, but it fires synchronously before the browser has a chance to paint:

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

function Tooltip() {
  const [tooltipHeight, setTooltipHeight] = useState(0);
  const tooltipRef = useRef();

  useLayoutEffect(() => {
    const height = tooltipRef.current.clientHeight;
    setTooltipHeight(height);
  }, []);

  return (
    
Tooltip content

The tooltip height is: {tooltipHeight}px

); }

In this example, we're using useLayoutEffect to measure the height of a DOM element synchronously before the browser paints.

When to use useLayoutEffect

  • When you need to make DOM measurements or mutations that should be applied synchronously before the browser paints
  • For animations that require measurements of DOM elements
  • When you want to avoid flickering caused by asynchronous updates

10. useDebugValue: Labeling Custom Hooks for DevTools

Last but not least, useDebugValue can be used to display a label for custom hooks in React DevTools.

How it works

useDebugValue accepts a value and an optional formatting function:

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

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  // ... Logic to determine if the friend is online ...

  useDebugValue(isOnline ? 'Online' : 'Offline');

  return isOnline;
}

function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);

  return (
    
  • {props.friend.name}
  • ); }

    In this example, we're using useDebugValue to display the friend's online status in React DevTools.

    When to use useDebugValue

    • In custom Hooks to provide more context about the Hook's state
    • For debugging complex custom Hooks
    • To improve the developer experience when working with custom Hooks

    Conclusion: Mastering React Hooks

    Wow, we've covered a lot of ground! From managing state with useState to optimizing performance with useMemo and useCallback, React Hooks offer a powerful and flexible way to build UI components. Let's recap the 10 Hooks we've explored:

    1. useState: For managing local state
    2. useEffect: For handling side effects
    3. useContext: For consuming context
    4. useReducer: For managing complex state logic
    5. useCallback: For optimizing performance of callbacks
    6. useMemo: For memoizing expensive computations
    7. useRef: For accessing DOM elements and storing mutable values
    8. useImperativeHandle: For customizing instance value
    9. useLayoutEffect: For synchronous effect execution
    10. useDebugValue: For labeling custom Hooks in DevTools

    Remember, the key to mastering React Hooks is practice. Start by incorporating them into your projects one at a time. As you become more comfortable, you'll find that Hooks can significantly simplify your code and make your components more reusable and easier to understand.

    Don't be afraid to experiment and combine different Hooks to solve complex problems. The React community is constantly coming up with new patterns and custom Hooks, so keep learning and sharing your discoveries!

    I hope this friendly guide has helped you get a better grasp on React Hooks. Happy coding, and may your components be forever functional and hook-tastic!

    "Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class." - React Documentation

    Now go forth and hook it up! ??

    版本声明 本文转载于:https://dev.to/nnnirajn/10-react-hooks-with-example-28kh?1如有侵犯,请联系[email protected]删除
    最新教程 更多>
    • 如何干净地删除匿名JavaScript事件处理程序?
      如何干净地删除匿名JavaScript事件处理程序?
      删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当需要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考...
      编程 发布于2025-07-01
    • MySQL中如何高效地根据两个条件INSERT或UPDATE行?
      MySQL中如何高效地根据两个条件INSERT或UPDATE行?
      在两个条件下插入或更新或更新 solution:的答案在于mysql的插入中...在重复键更新语法上。如果不存在匹配行或更新现有行,则此功能强大的功能可以通过插入新行来进行有效的数据操作。如果违反了唯一的密钥约束。实现所需的行为,该表必须具有唯一的键定义(在这种情况下为'名称'...
      编程 发布于2025-07-01
    • 如何避免Go语言切片时的内存泄漏?
      如何避免Go语言切片时的内存泄漏?
      ,a [j:] ...虽然通常有效,但如果使用指针,可能会导致内存泄漏。这是因为原始的备份阵列保持完整,这意味着新切片外部指针引用的任何对象仍然可能占据内存。 copy(a [i:] 对于k,n:= len(a)-j i,len(a); k
      编程 发布于2025-07-01
    • Python中嵌套函数与闭包的区别是什么
      Python中嵌套函数与闭包的区别是什么
      嵌套函数与python 在python中的嵌套函数不被考虑闭合,因为它们不符合以下要求:不访问局部范围scliables to incling scliables在封装范围外执行范围的局部范围。 make_printer(msg): DEF打印机(): 打印(味精) ...
      编程 发布于2025-07-01
    • 如何在GO编译器中自定义编译优化?
      如何在GO编译器中自定义编译优化?
      在GO编译器中自定义编译优化 GO中的默认编译过程遵循特定的优化策略。 However, users may need to adjust these optimizations for specific requirements.Optimization Control in Go Compi...
      编程 发布于2025-07-01
    • 如何使用组在MySQL中旋转数据?
      如何使用组在MySQL中旋转数据?
      在关系数据库中使用mySQL组使用mySQL组进行查询结果,在关系数据库中使用MySQL组,转移数据的数据是指重新排列的行和列的重排以增强数据可视化。在这里,我们面对一个共同的挑战:使用组的组将数据从基于行的基于列的转换为基于列。 Let's consider the following ...
      编程 发布于2025-07-01
    • 如何在php中使用卷发发送原始帖子请求?
      如何在php中使用卷发发送原始帖子请求?
      如何使用php 创建请求来发送原始帖子请求,开始使用curl_init()开始初始化curl session。然后,配置以下选项: curlopt_url:请求 [要发送的原始数据指定内容类型,为原始的帖子请求指定身体的内容类型很重要。在这种情况下,它是文本/平原。要执行此操作,请使用包含以下标头...
      编程 发布于2025-07-01
    • 如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
      如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
      在Visual Studio 2012 尽管已安装了MySQL Connector v.6.5.4,但无法将MySQL数据库添加到实体框架的“ DataSource对话框”中。为了解决这一问题,至关重要的是要了解MySQL连接器v.6.5.5及以后的6.6.x版本将提供MySQL的官方Visual...
      编程 发布于2025-07-01
    • Java为何无法创建泛型数组?
      Java为何无法创建泛型数组?
      通用阵列创建错误 arrayList [2]; JAVA报告了“通用数组创建”错误。为什么不允许这样做?答案:Create an Auxiliary Class:public static ArrayList<myObject>[] a = new ArrayList<myO...
      编程 发布于2025-07-01
    • 图片在Chrome中为何仍有边框?`border: none;`无效解决方案
      图片在Chrome中为何仍有边框?`border: none;`无效解决方案
      在chrome 在使用Chrome and IE9中的图像时遇到的一个频繁的问题是围绕图像的持续薄薄边框,尽管指定了图像,尽管指定了;和“边境:无;”在CSS中。要解决此问题,请考虑以下方法: Chrome具有忽略“ border:none; none;”的已知错误,风格。要解决此问题,请使用以下...
      编程 发布于2025-07-01
    • 如何使用Python的请求和假用户代理绕过网站块?
      如何使用Python的请求和假用户代理绕过网站块?
      如何使用Python的请求模拟浏览器行为,以及伪造的用户代理提供了一个用户 - 代理标头一个有效方法是提供有效的用户式header,以提供有效的用户 - 设置,该标题可以通过browser和Acterner Systems the equestersystermery和操作系统。通过模仿像Chro...
      编程 发布于2025-07-01
    • 如何处理PHP文件系统功能中的UTF-8文件名?
      如何处理PHP文件系统功能中的UTF-8文件名?
      在PHP的Filesystem functions中处理UTF-8 FileNames 在使用PHP的MKDIR函数中含有UTF-8字符的文件很多flusf-8字符时,您可能会在Windows Explorer中遇到comploreer grounder grounder grounder gro...
      编程 发布于2025-07-01
    • Python环境变量的访问与管理方法
      Python环境变量的访问与管理方法
      Accessing Environment Variables in PythonTo access environment variables in Python, utilize the os.environ object, which represents a mapping of envir...
      编程 发布于2025-07-01
    • 为什么我的CSS背景图像出现?
      为什么我的CSS背景图像出现?
      故障排除:CSS背景图像未出现 ,您的背景图像尽管遵循教程说明,但您的背景图像仍未加载。图像和样式表位于相同的目录中,但背景仍然是空白的白色帆布。而不是不弃用的,您已经使用了CSS样式: bockent {背景:封闭图像文件名:背景图:url(nickcage.jpg); 如果您的html,css...
      编程 发布于2025-07-01
    • 如何使用Regex在PHP中有效地提取括号内的文本
      如何使用Regex在PHP中有效地提取括号内的文本
      php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
      编程 发布于2025-07-01

    免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

    Copyright© 2022 湘ICP备2022001581号-3