看了阮一峰老师的 redux入门教程:http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
看的似懂非懂,自己动手写个demo来的检验一下:
这里关于原理讲解,请参照阮老师的教程。我直接上代码和思路:
1.使用github上的create-react-app官方脚手架,根据demo的需要,调整目录如下:
![](https://i-blog.csdnimg.cn/blog_migrate/4bc35b017455e8df531132b74ecd67c3.png)
2.实现的demo很简单,效果图如下:就是讲input输入的内容通过提交按钮添加到显示框里。
![](https://i-blog.csdnimg.cn/blog_migrate/4c3784e769d2f5f1f3bc0a377b1f6eac.png)
整个流程遵循:用户操作View---->View通过dispatch将action通知给发布出去---->Reducer接受当前状态的State和action传过来的数据,并进行处理返回一个新的State;
demo的数据流动: 点击Button将Input的输入值添加到一个数组中传给Display进行遍历显示;
首先:Input的输入会改变视图即需要通过dispatch将这个消息派发出去,即action、reducers就必不可少了。
action部分:
export
const
getInputContent = (
inputContent)
=> ({
type:
INPUTCONTENT,
inputContent })
reducers部分:
function
getInputContent(
state =
'',
action) {
switch (
action.
type) {
case
INPUTCONTENT:
return
action.
inputContent
default:
return
state
}
}
Input部分:
onChange=
{(
e)
=>
dispatch(
getInputContent(
e.
target.
value))
}
至此reducer返回一个新的state;
Button组件需要获取最新的Input的内容,即最新state
function
getInputText(
state) {
const {
getInputContent,
getAllContent } =
state.
reducers_demo1;
console.
log(
getInputContent);
return {
allContent:
getAllContent,
inputContent:
getInputContent
}
}
export
default
connect(
getInputText)(
Button);
获取这个state需要借助React-Redux 提供connect
方法,用于从 UI 组件生成容器组件。connect
的意思,就是将这两种组件连起来。
getInputText
是一个函数。建立一个从(外部的)state
对象到(UI 组件的)props
对象的映射关系。
getInputText
会订阅 Store,每当state
更新的时候,就会自动执行,重新计算 UI 组件的参数,从而触发 UI 组件的重新渲染。
connect
方法可以省略 getInputText
参数,那样的话,UI 组件就不会订阅Store,就是说 Store 的更新不会引起 UI 组件的更新。
所以我们从getInputText就可以获取当前的state从而获取Input组件的输入内容。
Button发表按钮点击时需要将Input的内容push到AllContent这样一个数组里,返回一个新的state;
action部分:
export
const
getAllContent = (
allContent)
=> ({
type:
AllCONTENT,
allContent })
reducers部分:注意:因为每次都是返回一个新的state;因为是引用类型的所以需要生成一个新的数组,否则视图不更新(踩坑)
function
getAllContent(
state = [],
action) {
switch (
action.
type) {
case
AllCONTENT:
return
action.
allContent.
concat()
//易错点
default:
return
state
}
}
Button部分:
onClick = ()
=> {
let {
inputContent,
dispatch,
allContent } =
this.
props;
if (
inputContent ===
"") {
return;
}
allContent.
push(
inputContent);
dispatch(
getAllContent(
allContent));
}
返回新的state,最后当然是需要显示到Display这个组件上。
同理利用connect关联来获取最新状态:
Display部分:
function
getAll(
state) {
let {
getAllContent } =
state.
reducers_demo1;
return {
getAllContent
}
}
export
default
connect(
getAll)(
Display);
获取allContent遍历出来显示到页面,完美。
reducer中用到了:
import {
combineReducers }
from
'redux'
const
demo1Reducer =
combineReducers({
getInputContent,
getAllContent,
initValue
})
export
default
demo1Reducer;
因为项目中最终有一个总的reducer;
关于创建store和将reducer注入到createStore中,入口文件index.js如下:
import
React
from
'react'
import
ReactDOM
from
'react-dom'
import {
Provider }
from
'react-redux'
import {
createStore }
from
'redux'
import
reducers
from
'./redux/rootReducer'
import
registerServiceWorker
from
'./registerServiceWorker'
import
Demo1
from
'./demo_01/main'
const
store =
createStore(
reducers)
ReactDOM.
render(
<
Provider
store=
{
store
}
>
<
Demo1
/>
</
Provider
>,
document.
getElementById(
'root')
)
registerServiceWorker();
其实文中记录的只是使用的方法思路,这个redux一开始接触的时候,感觉数据传输很混乱,不知从哪到哪。解释起来也比较绕口,理解就更有困难(可能是我个人理解能力问题)。看一遍阮老师的教程,直接上demo开干,具体详细的使用,需要结合demo源码和运行效果,这样才能更深层次的理解并懂得如何使用。
看不如做,边看边做,来的深刻。
也不知道该篇文章表述清楚没,此文只是个人的一些浅薄的理解,关于深层次的理解还得继续努力。
附:完整demo代码请移驾github上下载。