将 Redux 添加到现有的 React 应用程序

2023-11-21

我一直在开发一个 React 应用程序,并且已经到了需要 Redux 来处理它的某些方面的地步。

在阅读了一堆教程之后,我相当困惑于如何使我的“更智能”的组件变得“更笨”,并将函数移动到我的动作和减速器中。

例如,该应用程序的一方面更像是待办事项列表样式。

我的一堂课是这样开始的:

export default class ItemList extends React.Component {
  constructor() {
    super();
    this.state = { items: [],
                   completed: [],
                  };
    this.addItem = this.addItem.bind(this);
    this.completeItem = this.completeItem.bind(this);
    this.deleteItem = this.deleteItem.bind(this);
  }

  addItem(e) {
    var i = this.state.items;
    i.push({
      text: this._inputElement.value,
      paused: false,
      key: Date.now()
    });
    this.setState({ items: i });
    e.preventDefault();
    this._inputElement.value = '';
    this._inputElement.focus();
  }

  completeItem(e) {
    this.deleteItem(e);
    var c = this.state.completed;
    c.push({
      text: e.target.parentNode.parentNode.getElementsByClassName('item-name')[0].innerHTML,
      paused: false,
      key: Date.now()
    });
    this.setState({ completed: c });
  }

  deleteItem(e) {
    var i = this.state.items;
    var result = i.filter(function(obj) {
        return obj.text !== e.target.parentNode.parentNode.getElementsByClassName('item-name')[0].innerHTML;
    });
    this.setState({ items: result });
  }

  // ... more irrelevant code here ...

  // there's a function called createTasks that renders individual items

  render() {
    var listItems = this.state.items.map(this.createTasks);

    return <div className="item-list">
      <form className="form" onSubmit={this.addItem}>
        <input ref={(a) => this._inputElement = a}
               placeholder="Add new item"
               autoFocus />
        <button type="submit"></button>
      </form>

      {listItems}
    </div>;
  }
}

所以,正如你所看到的,它的逻辑性很强。我开始通过添加一个 Redux<Provider>在我的索引文件中,并制作了一个到目前为止相当空的基本减速器文件:

import { combineReducers } from 'redux';

const itemList = (state = {}, action) => {

};

// ... other irrelevant reducers

const rootReducer = combineReducers({
  itemList,
  // ...
});

export default rootReducer;

...我已经制作了一个动作文件,其中也没有太多内容。

我一直在努力弄清楚:

  • 我见过的大多数操作示例都只是返回某种 JSON,我在使用我的组件可以使用的 JSON 的减速器中返回什么?
  • 我的组件逻辑有多少是可重用的,还是我应该忘记它?为了尽可能多地重用我编写的代码,最好的方法是什么?

首先你需要了解 redux 如何与 React 配合使用的总体情况。

在此之前,我们首先了解什么是智能组件和哑组件。

智能组件

  1. 所有的代码逻辑都需要在这里处理
  2. 它们也称为容器。
  3. 他们与商店(又名状态管理)交互以更新您的组件。

哑组件

  1. 他们只是从你的容器中读取 props 并渲染你的组件
  2. 这只是 UI 视图,不应包含任何逻辑。
  3. 所有的样式/html/css 都在你的愚蠢组件中。

Here这是一篇很棒的文章,如果您仍然有疑问,可以阅读它来了解智能组件和愚蠢组件。

好的,现在让我们尝试了解 redux 的工作原理:-

  • 你的智能组件(又名容器)与你的 redux 存储交互
  • 您可以从容器中触发操作。
  • 您的操作调用您的 api
  • 您的操作结果通过减速器更新商店
  • 您的容器通过 mapStateToProps 函数读取存储,一旦存储中的值发生更改,它就会更新您的组件。

现在让我们考虑一下您的待办事项示例

TodoListContainer.js

class TodoListContainer extends Component {

  componentWillMount () {
    // fire you action action
  }


  render () {
    return (
      <Todos todos=={this.props.todos} />
    )
  }
}


function mapStateToProps(state) {
  const {todos} = state;
  return {
    todos;
  }
}

export default connect(mapStateToProps)(TodoListContainer)

TodoList.js

class TodoList extends Component {

  renderTodos() {
    return this.props.todos.map((todo)=>{
      return <Todo todo={todo} key={todo.id} />
    })
  }

  render () {
    return () {
      if (this.props.todos.length === 0) {
        return <div>No todos</div>
      }
      return (
        <div>
          {this.renderTodos()}
        </div>
      )
    }
  }
}

export default class TodoList

Todo.js

class Todo extends Component {

  render () {
    return (
      <div>
        <span>{this.props.todo.id}</span>
        <span>{this.props.todo.name}</span>
      </div>
    )
  }
}

Reducer

export default function todos(state={},action) {
  switch (action.type) {
    case 'RECEIVE_TODOS':
       return Object.assign(state,action.todos);
  }
}

action

function fetchTodos() {
  return(dispatch) => {
      axios.get({
    //api details
    })
    .then((res)=>{
      dispatch(receiveTodos(res.todos))
    })
    .catch((err)=>{
      console.warn(err)
    })
  }
}

function receiveTodos(todos) {
  return {
    type: 'RECEIVE_TODOS',
    todos
  }
}

现在,如果您已阅读 redux 文档,您会看到 actions 返回对象,那么我将如何调用返回函数而不是对象的 api。为此,我使用了 redux thunk,你可以阅读here.

我给你举了一个例子,你可以在其中获取待办事项。如果您想要执行其他操作,例如删除 Todo、添加Todo、修改 Todo,那么您可以在适当的组件中执行此操作。

  1. DeleteTodo - 您可以在 TodoListContainer 中执行。
  2. 添加Todo - 您可以在TodoListContainer 中执行。
  3. 更改状态(已完成/待定)- 您可以在 TodoListContainer 中执行。
  4. 修改Todo - 您可以在TodoContainer 中执行。

您还可以查看here详细的例子,但在此之前我想说的是应该先了解一下 redux 的基础知识,你可以找到here

P.S:我即时编写了代码,因此它可能无法正常工作,但只需稍加修改即可工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 Redux 添加到现有的 React 应用程序 的相关文章

随机推荐

  • 停止 argparse 通配文件路径

    我使用 python argparse 和以下参数定义 parser add argument path nargs 1 help File path to process 但是当我输入命令时wildcard争论 argparse全局所有文
  • 在不启用各种指令集的情况下如何编译?

    我正在尝试使用各种指令集重新编译一些软件 具体来说 SSE SSE2 SSE3 SSSE3 SSE4 1 SSE4 2 and AVX 我想看看代码的执行情况without这些指令集以确保我获得它们的全部效果 例如 我想用它来编译它 O2
  • 在 Rails 5 中,设置 config.active_record.schema_format = :sql 但仍然在 db:migrate 上创建 schema.rb

    在开发 Rails 5 应用程序时 我想使用structure sql代替schema rb 我们使用 PostGIS 进行大量自定义 SQL 调用 在config initializers database options rb我有以下内
  • 如何在 Rust 中创建一个可用作 Reader、Writer 或 Seek 的内存对象?

    我需要一个完全内存中的对象 我可以给它BufReader and BufWriter 类似于 Python 的东西StringIO 我想使用通常使用的方法写入和读取这样的对象Files 有没有办法使用标准库来做到这一点 其实有一个办法 Cu
  • Angular6 - 使用 ngx-translate 使用 API 调用后端加载翻译

    我想在前端使用 ngx translate 在应用程序加载时动态加载翻译 我的后端返回 JSON 格式的响应 例如 something something 我想在我的 TranslateLoader 上使用该输出而不是本地的en json
  • 使用按位运算求 n = 2**x 的指数 [n 以 2 为底的对数]

    有没有一种直接的方法可以仅使用按位运算从 2 的幂中提取指数 EDIT 虽然问题最初是关于按位运算的 但如果您想知道 该线程也值得一读 在 Y 2 的情况下找到 X 的最快方法是什么X 在Python中 我目前正在尝试优化例程 拉宾 米勒素
  • iOS 如何清除远程推送通知?

    所以我一直在阅读远程通知 并终于让它发挥作用 我们的应用程序正在接收来自我们服务器的通知 现在 如果我们的服务器满足特定条件 例如通知不再有效 我们希望删除或更新未读通知 我知道 静默 通知是唯一的方法 但我仍然对如何做到这一点感到困惑 如
  • 简单的 html 与 Javascript 生成的 html?

    在我的网络应用程序中 我想完全避免使用 html 并仅使用 javascript 来创建网页 dom 树 在 html 中以传统方式编写网页内容更快 div Some text div 或者使用 javascript dom render
  • 是否可以为 App Engine Flex 分配静态外部 IP?

    谷歌有文档为 App Engine Standard 设置外部 IP 但是 我需要为 App Engine Flex 设置外部 IP 我已按照教程操作 成功创建了一个带有连接到外部静态 IP 的 Cloud Router 和 Cloud N
  • 在 Python 调试器中中断成员函数

    这应该是一个微不足道的问题 但到目前为止我的搜索没有结果 我是第一次使用 Python 调试器 pdb 并且很高兴地发现使用 gdb 时熟悉的大多数命令 但是 当我去设置断点时parse 班级成员Jam解析器与声明 Pdb b JamPar
  • Delphi检查字符是否在'A'..'Z'和'0'..'9'范围内

    我需要检查字符串是否仅包含范围内的字符 A Z a z 0 9 所以我写了这个函数 function GetValueTrat aValue string string const number 0 9 const letter a z A
  • 将 ResultSet 传递到 Postgresql 函数中

    是否可以将 postgres 查询的结果作为输入传递到另一个函数中 作为一个非常人为的示例 假设我有一个查询 例如 SELECT id name FROM users LIMIT 50 我想创建一个函数my function它获取第一个查询
  • 从 TensorFlow 中给定的非均匀分布中进行无放回采样

    我正在寻找类似的东西numpy random choice range 3 replacement False size 2 p 0 1 0 2 0 7 在 TensorFlow 中 最近的Op看来是tf multinomial tf lo
  • 如何更新表中的 n 行?

    我需要更新表中满足条件的前 N 行 我知道我可以更新 Top N 但问题是 N 在 variable 中 UPDATE TOP N SET 不起作用 有没有办法做到这一点 我只是想念 这里没有特定的表定义 因为列是什么并不重要 如果我可以为
  • Java中的方法在某个位置创建文件,必要时创建目录?

    我正在尝试使用 java io 编写一个文件 我试图在该位置创建它 some path to somewhere then my file 创建文件时 路径上的任何目录可能存在 也可能不存在 我希望在需要时透明地创建目录 而不是因为没有这样
  • 多个微服务的 swagger 整合

    我有多个微服务 已经为其实现了 swagger 我想将所有 api 置于单个 swagger UI 下 我已按照以下链接执行此操作 但在STS的maven方法中尝试过 Swagger 合并 Github 示例 这是我在项目中的不同文件 Sp
  • jQuery.trigger() 函数后的回调

    我这里有一个小问题 我必须触发一个包含 post 的事件来加载表单并将其分配给 DOM 完成此操作后 我编辑了表单的字段 I tried when function type rank field trigger change calls
  • 以编程方式记录到 Sharepoint ULS

    我想在 Sharepoint Web 部件中记录内容 但我希望将其记录到 ULS 中 我发现的大多数示例都会登录到事件日志或其他文件 但我还没有真正找到用于登录 ULS 的示例 令人烦恼的是 Microsoft SharePoint Dia
  • 有没有办法获取类的变量和函数列表

    有没有办法获取类的变量和函数列表 例如 如果我的课程如下 class Person var age Int var name String func isOlder from person Person gt Bool func hasSa
  • 将 Redux 添加到现有的 React 应用程序

    我一直在开发一个 React 应用程序 并且已经到了需要 Redux 来处理它的某些方面的地步 在阅读了一堆教程之后 我相当困惑于如何使我的 更智能 的组件变得 更笨 并将函数移动到我的动作和减速器中 例如 该应用程序的一方面更像是待办事项