发布于 2026-01-06 6 阅读
0

React + Redux = React + Context DEV 的全球展示挑战赛,由 Mux 呈现:展示你的项目!

React + Redux = React + Context

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

我知道,已经有很多文章在讨论是否应该用 Context 替换 Redux,以及替换的利弊等等。但我认为这篇文章不属于这类讨论。

这纯粹是为了好玩😁。不过,你也可以在你的个人项目中尝试一下😉。

希望您已安装 NodeJS、npm 和 npx。

首先,我们来设置一个基本的 React 模板。进入你想进行实验的目录。运行,
npx create-react-app fooapp

更改应用程序目录cd fooapp

现在启动应用程序npm start。我希望应用程序已经启动并在您的浏览器中打开http://localhost:3000/

在src创建一个名为store 的文件夹。
cd src && mkdir store

store在.index.js和 .目录下创建两个文件handlers.js

index.js文件下store。我们将创建一个上下文。

/** index.js **/
import React from "react";
import PropTypes from "prop-types";

// Import all handlers
import * as handlers from "./handlers";

// Default state
const initialState = { todos:[] };

// Export the context
export const Context = React.createContext({ state: initialState, handlers });

// Export the provider
export const Provider = ({ children }) => {
  // This will be our global state
  const [state, setState] = React.useState(initialState);

  // Modify our hanlders with state and setState
  // Thanks Jose for this one 👍
   const modHandlers = Object.keys(handlers).map(key => handlers[key](state, setState))

  // Feed the state and modified handlers to the provider
  return (
    <Context.Provider value={{ state, handlers: modHanlders }}>
      {children}
    </Context.Provider>
  );
};

Provider.propTypes = {
  children: PropTypes.children.isRequired
};
Enter fullscreen mode Exit fullscreen mode

让我们创建处理程序来添加/删除待办事项列表中的事项。在store/handlers.js……

/* handlers.js*/
export const addTodo = (state, setState) => todo => {
  state.todos.push(todo);
  setState({ ...state });
}

export const removeTodo = (state, setState) => i => {
  delete state.todos[i];
  setState({ ...state });
};
Enter fullscreen mode Exit fullscreen mode

更新src/index.js文件。添加以下内容。

// src/index.js
import React from "react";
import ReactDOM from "react-dom";

import Todo from "./components/Todo";
import { Provider } from "./store";

function App() {
  return (
    <Provider>
      <div className="App">
        <h2 className="apptitle">Todo List</h2>
        <Todo />
      </div>
    </Provider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Enter fullscreen mode Exit fullscreen mode

如果出现错误请不要担心,我们会进行更新。

components在目录下创建一个文件夹src。将这三个文件添加到该文件夹​​中Todo.jsTodoField.js& TodoItem.js

在你的components/Todo.js文件中创建一个组件,用于存放待办事项列表。

// components/Todo.js
import React from "react";

import TodoItem from "./TodoItem";
import TodoField from "./TodoField";
import { Context } from "../store";

const Todo = props => {
  // Get the state from Context using useContext hook
  const { state } = React.useContext(Context);

  return (
    <div>
      <TodoField />
      <ul>
        {state.todos.map((todo, i) => (
          <TodoItem value={todo} index={i} />
        ))}
      </ul>
    </div>
  );
};

export default Todo;
Enter fullscreen mode Exit fullscreen mode

错误现在应该已经消失了。

在您的代码中components/TodoField.js添加以下代码。

// components/TodoField.js
import React from "react";

import { Context } from "../store";

const TodoField = () => {
  const [todo, setTodo] = React.useState(null);

  // Import the handlers from context
  const { handlers } = React.useContext(Context);

  // Handles form and other things
  const handleSubmit = e => {
    e.preventDefault();
    // Add the todo to the store
    handlers.addTodo(todo);
  };

  const handleChange = e => {
    setTodo(e.target.value);
  };

  // Form with field and submit button
  return (
    <form onSubmit={handleSubmit} onChange={handleChange}>
      <input type="text" value={todo} required />
      <input type="submit" value="Add Todo" />
    </form>
  );
};

export default TodoField;
Enter fullscreen mode Exit fullscreen mode

在您的代码中components/TodoItem.js添加以下代码。

// components/TodoItem.js
import React from "react";

import { Context } from "../store";

const TodoItem = ({ value, index }) => {
  const { handlers } = React.useContext(Context);
  const removeFromTodo = e => {
    handlers.removeTodo(index);
  };

  return (
    <li>
      {value} <button onClick={removeFromTodo}>x</button>
    </li>
  );
};

export default TodoItem;
Enter fullscreen mode Exit fullscreen mode

添加完所有文件后,您的应用应该可以正常运行。
待办事项清单应用

所有数据均来自同一存储库,并使用处理程序进行操作。

在 Lodash 中,您可以使用 get 和 set 方法来操作复杂的 JSON 对象。
附注:上述方法也可以处理基于 Promise 的异步操作。

实现代码已上传至codesandbox
祝您编码愉快!👩‍💻👨‍💻.... 😀

文章来源:https://dev.to/droidmakk/react-redux-react-context-3483