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

React Hooks 示例

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

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]删除
    最新教程 更多>
    • MySQL动态更新列使用INNER JOIN方法
      MySQL动态更新列使用INNER JOIN方法
      MySQL动态更新关联表列数据 本文介绍如何在MySQL中使用INNER JOIN动态更新目标表中的列。 我们的目标是根据共享的名称属性,将源表(tableA)中对应列的值更新到目标表(tableB)中的列。 可以使用以下UPDATE语句实现: UPDATE tableB INNER JOIN ...
      编程 发布于2025-04-19
    • 如何使用Python理解有效地创建字典?
      如何使用Python理解有效地创建字典?
      在python中,词典综合提供了一种生成新词典的简洁方法。尽管它们与列表综合相似,但存在一些显着差异。与问题所暗示的不同,您无法为钥匙创建字典理解。您必须明确指定键和值。 For example:d = {n: n**2 for n in range(5)}This creates a dicti...
      编程 发布于2025-04-19
    • 为什么使用Firefox后退按钮时JavaScript执行停止?
      为什么使用Firefox后退按钮时JavaScript执行停止?
      导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。要解决此问题并确保在后续页面访问中执行脚本,Firefox用户应设置一个空功能。 警报'); }; alert('inline Alert')...
      编程 发布于2025-04-19
    • Python中何时用"try"而非"if"检测变量值?
      Python中何时用"try"而非"if"检测变量值?
      使用“ try“ vs.” if”来测试python 在python中的变量值,在某些情况下,您可能需要在处理之前检查变量是否具有值。在使用“如果”或“ try”构建体之间决定。“ if” constructs result = function() 如果结果: 对于结果: ...
      编程 发布于2025-04-19
    • 如何在Chrome中居中选择框文本?
      如何在Chrome中居中选择框文本?
      选择框的文本对齐:局部chrome-inly-ly-ly-lyly solument 您可能希望将文本中心集中在选择框中,以获取优化的原因或提高可访问性。但是,在CSS中的选择元素中手动添加一个文本 - 对属性可能无法正常工作。初始尝试 state)</option> < op...
      编程 发布于2025-04-19
    • 您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
      您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
      在javascript console 中显示颜色是可以使用chrome的控制台显示彩色文本,例如红色的redors,for for for for错误消息?回答是的,可以使用CSS将颜色添加到Chrome和Firefox中的控制台显示的消息(版本31或更高版本)中。要实现这一目标,请使用以下模...
      编程 发布于2025-04-19
    • 如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
      如何修复\“常规错误:2006 MySQL Server在插入数据时已经消失\”?
      How to Resolve "General error: 2006 MySQL server has gone away" While Inserting RecordsIntroduction:Inserting data into a MySQL database can...
      编程 发布于2025-04-19
    • PHP如何在MySQL数据库中存储IP地址?
      PHP如何在MySQL数据库中存储IP地址?
      MySQL数据库IP地址使用PHP 使用PHP中存储IP地址时,使用PHP存储IP地址时,考虑到适当的字段类型和存储方法是至关重要的。 type 地址最合适的字段类型是int。尽管显然不匹配,但此选择还是由通过PHP IP2长函数从IP地址到整数的有效转换过程驱动的。要检索原始IP地址,可以使用...
      编程 发布于2025-04-19
    • 查找当前执行JavaScript的脚本元素方法
      查找当前执行JavaScript的脚本元素方法
      如何引用当前执行脚本的脚本元素在某些方案中理解问题在某些方案中,开发人员可能需要将其他脚本动态加载其他脚本。但是,如果Head Element尚未完全渲染,则使用document.getElementsbytagname('head')[0] .appendChild(v)的常规方...
      编程 发布于2025-04-19
    • 10款在线定制GIF制作工具推荐
      10款在线定制GIF制作工具推荐
      [2 在这篇文章中,我们收集了10种免费的在线GIF Maker工具,以制作您自己的自定义Ajax装载机 。易于创建自己的图像即可创建自己的自定义动画。 相关文章: 5在线加载ajax旋转器生成器工具 1。 gifmake.com 与(GIF,JPEG,PNG)构成图片,也可以分解动画gif。...
      编程 发布于2025-04-19
    • 如何使用PHP从XML文件中有效地检索属性值?
      如何使用PHP从XML文件中有效地检索属性值?
      从php $xml = simplexml_load_file($file); foreach ($xml->Var[0]->attributes() as $attributeName => $attributeValue) { echo $attributeName,...
      编程 发布于2025-04-19
    • 为什么HTML无法打印页码及解决方案
      为什么HTML无法打印页码及解决方案
      无法在html页面上打印页码? @page规则在@Media内部和外部都无济于事。 HTML:Customization:@page { margin: 10%; @top-center { font-family: sans-serif; font-weight: bo...
      编程 发布于2025-04-19
    • 如何有效地选择熊猫数据框中的列?
      如何有效地选择熊猫数据框中的列?
      在处理数据操作任务时,在Pandas DataFrames 中选择列时,选择特定列的必要条件是必要的。在Pandas中,选择列的各种选项。选项1:使用列名 如果已知列索引,请使用ILOC函数选择它们。请注意,python索引基于零。 df1 = df.iloc [:,0:2]#使用索引0和1 c...
      编程 发布于2025-04-19
    • 解决MySQL错误1153:数据包超出'max_allowed_packet'限制
      解决MySQL错误1153:数据包超出'max_allowed_packet'限制
      mysql错误1153:故障排除比“ max_allowed_pa​​cket” bytes 更大的数据包,用于面对阴谋mysql错误1153,同时导入数据capase doft a Database dust?让我们深入研究罪魁祸首并探索解决方案以纠正此问题。理解错误此错误表明在导入过程中接...
      编程 发布于2025-04-19
    • 在PHP中如何高效检测空数组?
      在PHP中如何高效检测空数组?
      在PHP 中检查一个空数组可以通过各种方法在PHP中确定一个空数组。如果需要验证任何数组元素的存在,则PHP的松散键入允许对数组本身进行直接评估:一种更严格的方法涉及使用count()函数: if(count(count($ playerList)=== 0){ //列表为空。 } 对...
      编程 发布于2025-04-19

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

    Copyright© 2022 湘ICP备2022001581号-3