首页 > web前端 > js教程 > 正文

使用 React 中的 useReducer Hook 掌握状态管理

Patricia Arquette
发布: 2024-10-20 13:02:02
原创
454 人浏览过

构建 React 应用程序时,管理状态可能会变得复杂,尤其是在处理相互依赖的多个状态变量时。如果您发现自己处于这种情况,那么是时候探索 useReducer Hook 的强大功能了!

什么是 useReducer?
useReducer Hook 是一个以可预测的方式管理状态的强大工具。它允许您以干净且有组织的方式管理复杂的状态逻辑,使您的代码更易于维护。

语法
useReducer Hook 接受两个参数:

useReducer(reducer, initialState)

登录后复制

reducer:包含自定义状态逻辑的函数。
初始状态:组件的初始状态,通常是一个对象。

如何运作

  1. 当前状态:基于最新调度操作的当前状态值。
  2. Dispatch Method:一个函数,可以让你向reducer发送action来更新状态

1.示例:
这是如何使用 useReducer Hook 来管理计数器的简单示例:

import React, { useReducer } from "react";

// Define the initial state
const initialState = { count: 0 };

// Define the reducer function
const reducer = (state, action) => {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      return state;
  }
};

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  // Inline styles
  const containerStyle = {
    maxWidth: "400px",
    margin: "50px auto",
    padding: "20px",
    borderRadius: "10px",
    boxShadow: "0 4px 20px rgba(0, 0, 0, 0.2)",
    textAlign: "center",
    backgroundColor: "#ffffff",
    fontFamily: "'Roboto', sans-serif",
  };

  const headingStyle = {
    fontSize: "2.5rem",
    margin: "20px 0",
    color: "#333333",
  };

  const buttonStyle = {
    margin: "10px",
    padding: "12px 24px",
    fontSize: "1.1rem",
    border: "none",
    borderRadius: "5px",
    cursor: "pointer",
    transition: "background-color 0.3s, transform 0.3s",
    outline: "none",
    boxShadow: "0 2px 10px rgba(0, 0, 0, 0.1)",
  };

  const incrementButtonStyle = {
    ...buttonStyle,
    backgroundColor: "#28a745",
    color: "white",
  };

  const decrementButtonStyle = {
    ...buttonStyle,
    backgroundColor: "#dc3545",
    color: "white",
  };

  // Hover and active styles
  const buttonHoverStyle = {
    filter: "brightness(1.1)",
    transform: "scale(1.05)",
  };

  return (
    <div style={containerStyle}>
      <h1 style={headingStyle}>Count: {state.count}</h1>
      <button
        style={incrementButtonStyle}
        onMouseOver={(e) =>
          (e.currentTarget.style = {
            ...incrementButtonStyle,
            ...buttonHoverStyle,
          })
        }
        onMouseOut={(e) => (e.currentTarget.style = incrementButtonStyle)}
        onClick={() => dispatch({ type: "increment" })}
      >
        Increment
      </button>
      <button
        style={decrementButtonStyle}
        onMouseOver={(e) =>
          (e.currentTarget.style = {
            ...decrementButtonStyle,
            ...buttonHoverStyle,
          })
        }
        onMouseOut={(e) => (e.currentTarget.style = decrementButtonStyle)}
        onClick={() => dispatch({ type: "decrement" })}
      >
        Decrement
      </button>
    </div>
  );
}

export default Counter;

登录后复制

输出:

Mastering State Management with the useReducer Hook in React

2.示例:

import React, { useReducer, useState } from "react";

// Define the initial state
const initialState = {
  todos: [],
};

// Define the reducer function
const reducer = (state, action) => {
  switch (action.type) {
    case "ADD_TODO":
      return { ...state, todos: [...state.todos, action.payload] };
    case "REMOVE_TODO":
      return {
        ...state,
        todos: state.todos.filter((todo) => todo.id !== action.payload),
      };
    default:
      return state;
  }
};

function TodoApp() {
  const [state, dispatch] = useReducer(reducer, initialState);
  const [inputValue, setInputValue] = useState("");

  const handleAddTodo = () => {
    if (inputValue.trim()) {
      dispatch({
        type: "ADD_TODO",
        payload: { id: Date.now(), text: inputValue },
      });
      setInputValue(""); // Clear input field
    }
  };

  // Internal CSS
  const styles = {
    container: {
      maxWidth: "600px",
      margin: "50px auto",
      padding: "20px",
      borderRadius: "10px",
      boxShadow: "0 4px 20px rgba(0, 0, 0, 0.1)",
      backgroundColor: "#f9f9f9",
      fontFamily: "'Arial', sans-serif",
    },
    heading: {
      textAlign: "center",
      fontSize: "2.5rem",
      marginBottom: "20px",
      color: "#333",
    },
    input: {
      width: "calc(100% - 50px)",
      padding: "10px",
      borderRadius: "5px",
      border: "1px solid #ccc",
      fontSize: "1rem",
      marginRight: "10px",
    },
    button: {
      padding: "10px 15px",
      fontSize: "1rem",
      border: "none",
      borderRadius: "5px",
      backgroundColor: "#28a745",
      color: "white",
      cursor: "pointer",
      transition: "background-color 0.3s",
    },
    buttonRemove: {
      padding: "5px 10px",
      marginLeft: "10px",
      fontSize: "0.9rem",
      border: "none",
      borderRadius: "5px",
      backgroundColor: "#dc3545",
      color: "white",
      cursor: "pointer",
      transition: "background-color 0.3s",
    },
    todoList: {
      listStyleType: "none",
      padding: 0,
      marginTop: "20px",
    },
    todoItem: {
      display: "flex",
      justifyContent: "space-between",
      alignItems: "center",
      padding: "10px",
      borderBottom: "1px solid #ccc",
      backgroundColor: "#fff",
      borderRadius: "5px",
      marginBottom: "10px",
    },
  };

  return (
    <div style={styles.container}>
      <h1 style={styles.heading}>Todo List</h1>
      <div style={{ display: "flex", justifyContent: "center" }}>
        <input
          style={styles.input}
          type="text"
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
          placeholder="Add a new todo"
        />
        <button style={styles.button} onClick={handleAddTodo}>
          Add Todo
        </button>
      </div>
      <ul style={styles.todoList}>
        {state.todos.map((todo) => (
          <li style={styles.todoItem} key={todo.id}>
            {todo.text}
            <button
              style={styles.buttonRemove}
              onClick={() =>
                dispatch({ type: "REMOVE_TODO", payload: todo.id })
              }
            >
              Remove
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default TodoApp;

登录后复制

输出:

Mastering State Management with the useReducer Hook in React

useReducerHook 是 React 工具包的绝佳补充。它使您能够有效地处理复杂的状态管理,使您的应用程序更加健壮且更易于维护。在您的下一个项目中尝试一下,让您的状态管理更上一层楼!

以上是使用 React 中的 useReducer Hook 掌握状态管理的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!