[译】Redux入门教程(一)

前言

老外写技术文章真是叼,这是国外的一个程序员写的一个简单易懂,循序渐进的Redux教程,本着共享的精神,就翻译出来给大家一起看,文章最后有链接,不想看我翻译的直接去看原文吧。

下面是原教程的英文目录

这篇先更三分之一左右,如果小伙伴们喜欢的话,我再更剩下的,如果没人看,我没动力更啊

开始享受你的阅读之旅吧!

本次更新目录

  • 1. 谁适合学习这篇指南
  • 2. 你将会学到什么
  • 3. 一个小型的React开发环境
  • 4. 什么是state
  • 5. Redux解决了什么问题
  • 6. 为什么你应该学习Redux
  • 7. 你应该使用Redux吗
  • 8. 开始认识Redux的store
  • 9. 开始认识Redux的reducers
  • 10. 开始认识Redux的actions

正文

当我第一次学习Redux的时候,我希望找到最简单的教程。

尽管网上有大量的教程,我却依然无法理解Redux的一些概念

我知道什么是state, 但是ations, creators, 和reducers又是什么呢?我对此一头雾水

最重要的是,我依然不知道怎么将React和Redux结合起来

这些天,我开始写我自己的Redux教程,因此,我也学到了很多, 通过写这个指南,我自学了Redux的基础,我希望这份教程可以帮助到那些想要学习React和Redux的人

谁适合学习这篇指南

下面的Redux教程正是为这些人准备的:

  • 你已经很好地掌握了Javascript, ES6和React
  • 你期望用最简单的方式学会Redux

你将会学到什么

接下来的指南中你将会学到:

  1. 什么是Redux
  2. 怎样在React中使用Redux

一个小型的React开发环境

在开始之前,确定你有一个React的开发环境

你可以参照我另外一篇教程如何搭建React, webpack, 和Babel环境, 或者你也可以用create-react-app脚手架来搭建

什么是state

为了理解Redux,你必选先理解state

如果你之前使用过React, 那么你对state这个术语就不会陌生了

比如你之前已经写过类似于下面的有状态的React组件

import React, { Component } from "react";
class ExampleComponent extends Component {constructor() {super();this.state = {articles: [{ title: "React Redux Tutorial for Beginners", id: 1 },{ title: "Redux e React: cos'è Redux e come usarlo con React", id: 2 }]};}render() {const { articles } = this.state;return <ul>{articles.map(el => <li key={el.id}>{el.title}</li>)}</ul>;}
}
复制代码

一个有状态的React组件是一个javascrit的ES6的类class

每个有状态的React组件有它自己的状态

在React组件中,状态state管理数据,组件可能将数据渲染,显示给用户

状态在响应行为和事件的时候可能会发生变化, 在React中,组件可以通过setState更新自己的状态

但是,状态到底是什么,这个术语state并没有绑定在React中,状态一直在你身边,即使最简单的JavaScript应用都有状态,考虑下面的例子:

用户点击了一个按钮

最上层出现了一个弹框

看看,在这个微不足道的交互中就有一个状态,我们必须处理

我们可以用一个JavaScript 对象来描述初始状态

var state = {buttonClicked: 'no',modalOpen: 'no'
}
复制代码

当用户点击按钮之后,这个对象就变成了

var state = {buttonClicked: 'yes',modalOpen: 'yes'
}
复制代码

除了将这些状态储存在一个对象中,你如何跟踪JavaScript的这些状态?是否有一个库可以帮我们更可靠地追踪这些状态

Redux解决了什么问题

一个典型的Javascript应用充满了状态, 例如:

  • 用户看到了什么(data)
  • 我们在获取什么数据
  • 我们展示给用户的url是什么
  • 在页面里面选中了哪些条目
  • 应用中是否有错误?这个也是状态

状态在Javascript中无处不在, 你可以想象一下一个React应用有多少状态吗?

当然,只要你的应用一直保持很小,你可以用一个父组件来维持这些状态,但是当你给你的应用添加更多行为的时候,事情就变得棘手了。

有时候,我们可能希望持续地跟踪并且获取到状态的变化,但是,前端开发者不应该处理这个业务逻辑, 所以还有什么可选方案来管理React组件的状态呢?

** Redux**就是其中之一 Redux解决了一个刚开始的时候可能不那么明显的难题,它给了每个React组件所需要的状态

Redux在一个地方维持状态

当然,使用Redux, 获取和管理状态就独立于React之外了, 这种方式的好处刚开始可能不是那么明显,当你越来越了解Redux的时候,好处就会变得越来越清晰

接下来,我们来看看你为什么应该学习Redux以及什么时候应该在你的应用中使用Redux,首先先来了解为什么你应该学习Redux

为什么你应该学习Redux

你是否想学习Redux但是却不知从何学起,Redux让大多数开始学习的人望而却步,但是你不应该被吓到,Redux并没有那么难,关键是:不要急着去学Redux,除非你对此有目标和热情,你才应该开始学习它

别着急, 我开始学习Redux是因为:

  • 我有百分百的兴趣了解Redux的工作原理
  • 我迫切地希望提高我的React技能
  • React和Redux结合是十分普遍的
  • Redux是通用独立的框架,一旦学会了,可以到处使用(vue, Angular)

那么,Redux是一个好的汇报吗?状态遍布在Javascript应用中,所以状态管理在JavaScript 中一直是个未解决的难题

另一个事实就是:真正的JavaScript应用大多数都是使用状态管理库

那么Redux在未来会消失吗? 有这种可能,但是这种模式将会长存,它对你前端开发事业极为宝贵

最后,学习Redux或者相关的状态管理库是必须的,即使学习曲线很陡峭

你应该使用Redux吗

使用Redux,Flux或者Mobx来管理状态完全取决于你

可能你根本不需要这些库,使用它们的代价就是,他们在你的应用中加了一层抽象

但是我更倾向于认为Redux是一个有用的投资,而不是成本

另外一个开始学习Redux的人常见的问题就是:怎么知道什么时候你的应用需要使用Redux?

如果你认为没有不二法则来确定你什么时候需要使用Redux来管理状态, Redux也给JavaScript开发者提供了很多便利, 调试,action重放等等

当我开始一个React项目的时候,我总是控制不住直接将Redux加入到项目中,但是作为开发者,我们可能就会让代码臃肿了

所以,什么时候你猜应该将Redux添加到你的项目中?

在挑选Redux之前,先花点时间来探索下可选的模式, 特别是需要深入理解React的state和props

Dave Ceddia有一篇很好的文章children props as an alternative before reaching for Redux,里面有很多关于用子组件的props来作为Redux代替方案的见解

不要忘记就算之后添加了Redux , React项目也可以很容易地被重构

我总结的你需要考虑使用Redux的情况如下:

  • 很多React组件需要获取同样的状态,但是没有任何父子关系
  • 用props一层层往下传递状态给多个组件 让你棘手了

不用担心,如果上面的情况对你没有任何意义,Dan Abramov曾经说过,“Flux就是眼镜一样,当你需要他们的时候你会知道的”

在进一步深入之前,你需要花店时间理解Redux解决了什么问题以及你是否有动力去学习它

注意,Redux对小型应用没有那么游泳,在大型应用中它才会大放光彩,无论如何, 即使你当前不是在开发大型应用,学习Redux也不会有坏处

接下来,我们将开始介绍一些概念

  • Redux基本原则
  • Redux和React结合

再一次重申,确定你搭建好了React的开发环境:你可以跟着 How to set up React, webpack, and Babel这个教程来,或者使用create-react-app脚手架来搭建

开始认识Redux的store

Actions, Reducers,我对这些还是有几分了解的,但是有件事我不明白:这些东西是怎么聚合在一起的?

在Redux中store精心安排了所有的东西,和我重复一遍:store

store对于Redux来说就像人的大脑一样:它是某种魔法

Redux的store是根基性的东西,整个应用的状态存在store之中

转到你的React开发环境,安装Redux:

npm i redux --save-dev
复制代码

为store创建一个目录

mkdir -p src/js/store
复制代码

src/js/store中创建一个新文件index.js,初始化store

// src/js/store/index.js
import { createStore } from "redux";
import rootReducer from "../reducers/index";
const store = createStore(rootReducer);
export default store;
复制代码

从上面的代码你可以看出,store是createStore的返回结果,createStore是一个函数,来自redux库

createStore接受一个reducer作为第一个参数,因此我们传递了rootReducer

你也可以传递一个初始的state给createStore ,这对服务端渲染有用,但是现在我们不必关心这个

最重要的概念就是redux的state来自于reducers,我们再说的清楚点,reducers产生你应用的状态

了解了这个,我们可以继续学习我们的第一个Redux reducer了

开始认识Redux的reducers

尽管初始的state对服务端渲染有用,在Redux中,state必须从reducers中返回

那么什么是reducer呢?

一个reducer是一个JavaScript函数,一个reducer函数接收两个参数当前的state和一个action(马上我们会介绍更多关于action的东西)

在一个平常的React组件中,本地的状态变化是通过setState来改变的, 然而,在Redux中,你不可以这么做。 Redux的第三个原则是state是不可变的,并且不能改变他们

这就是为什么reducer必须是纯函数,一个纯函数是对于一个特定输入总是会返回同样输出的函数

创建一个reducer并不难,它仅仅是一个有两个参数的JavaScript函数

在我们的示例中,我们将会创建一个简单的reducer,它接受初始的state作为第一个参数,至于第二个参数,我们提供一个action,现在reducer除了返回初始的state什么都不会做

为根reducer创建一个目录

mkdir -p src/js/reducers
复制代码

接着在src/js/reducers里面创建一个index.js文件

// src/js/reducers/index.js
const initialState = {articles: []
};
function rootReducer(state = initialState, action) {return state;
};
export default rootReducer;
复制代码

我承诺保证这篇指南尽可能地简单,这就是为什么我们的第一个reducer很傻了:它返回初始的state,除此之外,就什么都没做了

注意初始的state是怎么作为一个默认参数传递的

在接下来的章节中,我们将在里面添加一个action, 在这里事情就会变得有趣了

开始认识Redux的actions

毫无疑问,reducers是Redux最重要的概念**,reducers产生应用的状态**

但是一个reducer是怎么知道什么时候产生下一个状态呢

Redux的第二个原则就是改变的状态的唯一方法是发送信号给store, 这个信号就是一个action, 派发action就是一个发送信号的过程

现在,你怎么改变一个不可变的state,你做不到的,新产生的state是当前state添加了新数据后的一个副本,前一个state根本没发生变化

这就是你需要知道的东西

要明白,Redux的action仅仅是JavaScript对象,下面是一个action

{type: 'ADD_ARTICLE',payload: { title: 'React Redux Tutorial', id: 1 }
}
复制代码

每个action需要一个type属性来描述状态怎样变化

你也可以申明一个payload,在上面的例子中,payload是一个新文章article,随后一个reducer将会将这个新文章添加到当前的state

最佳的实践是在一个函数里面包裹每个action, 这种函数就叫action creator

现在通过创建一个简单的Redux 的action,我们可以把所有的东西都整合在一起了

为actions创建一个目录

mkdir -p src/js/actions
复制代码

然后在这个目录里面创建index.js文件

// src/js/actions/index.js
export function addArticle(payload) {return { type: "ADD_ARTICLE", payload }
};
复制代码

type属性仅仅是一个字符串而已

reducer将会使用这个字符串来确定怎么计算出下一个state

由于字符串很容易打印出错和重复,因此将action的type申明为常量更好

这种方式可以避免很难调试的错误

创建一个新目录

mkdir -p src/js/constants
复制代码

然后在这个目录里面创建一个action-types.js文件

// src/js/constants/action-types.js
export const ADD_ARTICLE = "ADD_ARTICLE";
复制代码

现在打开src/js/actions/index.js, 并且使用action types来更新action

import { ADD_ARTICLE } from "../constants/action-types";
export function addArticle(payload) {return { type: ADD_ARTICLE, payload };
}
复制代码

我们还差一步就可以拥有一个可以运行的Redux应用了,让我们来重构我们的reducer!


华丽的风格线,哈哈 本篇内容翻译完毕,溜了,肚子饿的呱呱叫了。

附上原文链接 www.valentinog.com/blog/redux/

转载于:https://juejin.im/post/5cd68669518825690233ccf9

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448830.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Intellij Idea 打包 java 工程为可执行 jar 包

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 其实还有个简单多了方法&#xff0c;见&#xff1a; 超简单方法&#xff1a; Intellij Idea 把 java 工程打成可运行的 jar 步骤&#x…

QuickStart系列:docker部署之Gitlab本地代码仓库

gitlab是可以在本地搭建的使用git作为源代码管理的仓库。 运行环境&#xff1a; win10vmware14docker7docker 1. 使用命令拉取镜像&#xff08;非必须&#xff0c;耗时比较久&#xff0c;这里以ce为准&#xff0c;ce是社区版&#xff0c;ee是企业版&#xff09;&#xff1a; do…

超简单方法: Intellij Idea 把 java 工程打成可运行的 jar

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 找到 Intellij Idea 最下面的 Terminal 选项&#xff0c;并点击进入该界面。 2. 在光标位置输入命令&#xff1a;mvn clean 。清理…

LDAP-轻量级目录访问协议(统一认证)

概念 LDAP是轻量目录访问协议&#xff0c;英文全称是Lightweight Directory Access Protocol&#xff0c;一般都简称为LDAP。 参考资料 LDAP概念和原理介绍 我花了一个五一终于搞懂了OpenLDAP LDAP-Apache Directory Studio使用&#xff08;创建DC.OU及用户&#xff09; 转载于…

kafka集群搭建(消息)

1、Kafka使用背景在我们大量使用分布式数据库、分布式计算集群的时候&#xff0c;是否会遇到这样的一些问题&#xff1a;我们想分析下用户行为&#xff08;pageviews&#xff09;&#xff0c;以便我们设计出更好的广告位我想对用户的搜索关键词进行统计&#xff0c;分析出当前的…

[转]在Windows 下使用OpenCL

目前&#xff0c;NVIDIA和AMD的Windows driver均有支援OpenCL&#xff08;NVIDIA的正式版driver是从195.62版开始&#xff0c;而AMD则是从9.11版开始&#xff09;。NVIDIA的正式版driver中包含OpenCL.dll&#xff0c;因此可以直接使用。AMD到目前为止&#xff0c;则仍需要安装其…

docker 之 Dockerfile 实践

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 上一篇介绍了Dockerfile中使用的指令&#xff0c;现在开始进行指令实践 先查看下本地的镜像&#xff0c;选一个作为base image&#xf…

tomcat启动后命令行日志中文乱码

这是日志的编码设置和窗体的编码格式不一致。 将 conf\logging.properties 文件中的 UTF-8 改成 GBK 重启tomcat &#xff08;右键cmd标题栏部分&#xff0c;可以查看cmd属性&#xff09; 转载于:https://www.cnblogs.com/Echiops/p/10974587.html

Coursera机器学习笔记(一) - 监督学习vs无监督学习

转载 http://daniellaah.github.io/2016/Machine-Learning-Andrew-Ng-My-Notes-Week-1-Introduction.html 一. 监督学习 什么是监督学习? 我们来看看维基百科中给出的定义: 监督式学习&#xff08;英语&#xff1a;Supervised learning&#xff09;&#xff0c;是一个机器学习…

基于OpenCL的mean filter性能

1.对于一个标准的3*3 均值滤波&#xff0c;kernel代码如下&#xff1a; 使用buffer/image缓冲对象 __kernel void filter(__global uchar4* inputImage, __global uchar4* outputImage, uint N) {int x get_global_id(0);int y get_global_id(1);int width get_global_size(…

Docker 实战:编写 Dockerfile

一、编译镜像 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 编译镜像 Dockerfile类似于Makfile&#xff0c;用户使用docker build就可以编译镜像&#xff0c;使用该命令可以设置编译…

dubbo-环境搭建,实现一个简单地dubbo实例(附github地址)

一、建立maven模块和provider、consumer、service子模块&#xff0c;其中service是开发接口的模块 建立一个maven模块&#xff0c;不选择样板&#xff0c;直接next知道完成&#xff0c;建立三个子模块,建立完后发现各个模块的java目录不是源目录 右键——>make Directory as…

static 二次理解

当api底层用到static修饰的话&#xff0c;因为是类的&#xff0c;此容器中只有一份转载于:https://blog.51cto.com/jiaxiaoxu/2394844

AMD 5XXX 系列显卡的 peak bandwidth计算

在ATI Stream Computing Programming Guide中&#xff0c;例举了AMD 5系列显卡的参数信息。 我比较关注其中Peak bandwidths的计算&#xff0c;以便在opencl程序测试bandwidth利用率。 下面&#xff0c;我以5870为例&#xff0c;探讨一下如何计算得到这些结果&#xff1a; L1 c…

Docker : Dockerfile 定制镜像

使用 Dockerfile 定制镜像 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写…

动态规划 最长上升子序列

题意&#xff1a;给出一个序列&#xff0c;求它的最长上升子序列的长度 题目链接&#xff1a;https://ac.nowcoder.com/acm/problem/26156 输入:n代表长度&#xff0c;然后是一个字符串 分析&#xff1a;用dp[i]表示长度为i1的上升子序列末尾元素的最小值&#xff08;一开始初始…

解说redis中如何实现高可用

redis中为了实现高可用&#xff08;High Availability&#xff0c;简称HA&#xff09;&#xff0c;采用了如下两个方式&#xff1a;主从复制数据。采用哨兵监控数据节点的运行情况&#xff0c;一旦主节点出现问题由从节点顶上继续进行服务。主从复制redis中主从节点复制数据有全…

OpenCL memory object 之 Global memory (1)

这篇日志是学习AMD OpenCL文档时候的总结。 OpenCL用memory object在host和device之间传输数据&#xff0c;memory object由runtime&#xff08;运行库&#xff0c;driver的一部分&#xff09;来管理。 OpenCL中的内存对象包括buffer以及image&#xff0c;buffer是一维数据元素…

Docker: dockerfile 使用介绍

Docker简介 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Docker项目提供了构建在Linux内核功能之上&#xff0c;协同在一起的的高级工具。其目标是帮助开发和运维人员更容易地跨系统跨…

【Hello CSS】第六章-文档流与排版

作者&#xff1a;陈大鱼头github&#xff1a; KRISACHAN正常流 什么是“正常流”&#xff1f; 其实就是我们日常所说的“文档流”。 在W3C官方文档里对应的是“normal flow”。 正常流的盒子属于格式化上下文(FC)&#xff0c;在CSS2.2中可以是表格、块或内联。 在CSS3中引入了f…