动手实现react-redux之一初步

通过 redux 动手实现可以看到它并不复杂,很多看起来奇怪的约定或者约束都是为了解决特定问题而存在的,把这些问题想清楚之后就不难理解那些奇怪的约定了,下面我们试着来实现下可以使 React 和 redux 相互结合一个库 react-redux。

在 React 中应用的状态存在可能被多个组件依赖或者影响,而 React 并没有提供很好的解决方案,我们只能把状态提升到依赖或者影响这个状态的所有组件的公共父组件上,我们把这种行为叫做状态提升。但是需求不停变化,导致状态一直在不断的提升,然后一层层的传递,这显然不是我们想要的。

后来 React 提供了 context 的概念,将共享状态放到父组件的 context 上,这个父组件下所有的子组件 都可以从 context 中直接获取状态,而不要一层层传递了。但是直接从 context 里面存放、获取数据增强了组件的耦合性;并且所有组件都可以修改 context 里面的状态就像谁都可以修改共享状态一样,导致让程序不可预测。

而 redux 中的 store 的数据不是谁都能修改,而是约定只能通过 dispatch 来进行修改,这样的话将 redux 和 context 结合起来,每个组件既可以去 context 里面获取 store 从而获取状态,又不用担心它们乱改数据了。下面我们来试一下。

使用 create-react-app 新建一个工程,然后安装 prop-types , 删除 src 下面除 index.jsindex.css之外的文件,然后在 src 下面新建三个文件 Header.js、Content.js、ThemeSwitch.js。

src/Header.js:

1
2
3
4
5
6
7
8
9
10
11
12
import React, { Component } from "react";
import PropTypes from "prop-types";

class Header extends Component {
render() {
return (
<h1>React-Redux是什么</h1>
);
}
}

export default Header;

src/ThemeSwitch.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React, { Component } from "react";
import PropTypes from "prop-types";

class ThemeSwitch extends Component {
render() {
return (
<div>
<button>设置主题颜色red</button>
<button>设置主题颜色green</button>
</div>
);
}
}

export default ThemeSwitch;

src/Content.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, { Component } from "react";
import PropTypes from "prop-types";
import ThemeSwitch from "./ThemeSwitch";

class Content extends Component {
render() {
return (
<div>
<p>React-Redux是Redux的官方React绑定库。它能够使你的React组件从Redux store中读取数据,并且向store分发actions以更新数据</p>
<ThemeSwitch />
</div>
);
}
}

export default Content;

修改 src/index.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import React, { Component } from "react";
import PropTypes from "prop-types";
import ReactDOM from "react-dom";
import Header from "./Header";
import Content from "./Content";
import "./index.css";

class Index extends Component {
render() {
return (
<div>
<Header />
<Content />
</div>
);
}
}

ReactDOM.render(
<Index />,
document.getElementById("root")
);

然后 npm start 启动项目,打开页面就可以看到效果。

目前只是完成项目搭建,状态和逻辑都还没添加,后面继续。

参考

http://huziketang.mangojuice.top/books/react/