Redux demo 1
笔记
1 创建store
引入redux 里面的一个createStore 方法 , 把 reducer 传递给store
import {createStore} from ‘redux’
const store = createStore(reducer)
2 创建reducer,
作用 负责存储整个项目中的数据,怎么处理,怎么传都由reducer负责 ,把数据传递给store,
const defaultState = {
inputValue:"123",
list : [4,5]
}
export default (state = defaultState,actions) => { // state 指的是 笔记本里的空数据
return state;
}
reducer 返回的必须是一个函数,里面有两个参数,state,action
redux 里面 组件通过 store.dispatch(action)
通过dispatch把东西传递给store ,dispatch本意思就是 派发的意思
reducer里面的state存的是上一次store存的数据, action指的是用户传递过来的那句话
经过reducer处理过后,返回一个新数据 替换掉 store里面的老数据
通过store.subscribe
把reducer传递过去的 state新值 映射到 组件中
store.subscribe
==============================================================
官网关于redux 的核心思想的一张图 划重点!!!
举个通俗易懂的例子,来讲讲redux的思想
就好比一个人去图书馆借书,借书的人看作一个组件component
,store
就好比思图书馆的管理员,我现在要去图书馆借书,首页我得需要说一句借书的话,这句话,就是redux
里面的action
,这个action
怎么才能让图书馆管理员Store
知道呢?通过dispatch
来完成,也就是后期的store.dispatch(action)
来传递组件里面的action
到store
里面,dispatch
英文就是分发,派遣的意思,也可以理解为发请求的意思。现在图书馆管理员Store
收到来我(组件)需要借书的请求(action
)后,他得需要去查询一本手册?才能知道我,需要借啥样的书,这个手册就是redux
里面的reducer
,好,现在图书馆管理员Store
去手册reducer
里面查询后,找到来我需要借的书,会把这个结果返回给图书馆管理员Store
,即 后面代码里的newState
,图书馆管理员Store现在获取到来返回的借书结果newState
后,需要把这个结果告诉给我,即一开始借书的组件,现在问题来了,我怎么才能知道有没有找到这本书,即 我怎么才能时刻的知道借书的结果呢????
所以为了解决这个问题,需要在组件(我)里面,通过 subscribe
来订阅 图书馆管理元Store
里面 state
的改变,只要 state
一改变,组件里面就能监听到,通过一下代码完成这项监听动作
store.subscribe(this.handleStorechange) // 监听 store 里面值的变化
好 ,现在上 redux 学习的练手demo,toDoList demo
index.js-这个文件是创建store,即上文中的图书馆管理员
import {createStore} from 'redux'
import reducer from './reducer'
const store = createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
export default store;
todoList.js -普通组件-即上文中的借书的人
import React, { Component } from 'react';
import { Input ,Button ,List} from 'antd';
import store from '../store/index'
class TodoList extends Component {
constructor(props){
super(props)
this.state = store.getState()
console.log(this.state)
this.handleInputChange = this.handleInputChange.bind(this)
this.handleStorechange = this.handleStorechange.bind(this)
this.handleBtnClick = this.handleBtnClick.bind(this)
store.subscribe(this.handleStorechange) // 监听 store 里面值的变化
}
handleInputChange(e){
const action = {
type:'change_input_value',
value : e.target.value
}
store.dispatch(action)
}
handleStorechange(){
console.log('handleStorechange changed')
console.log(1,store.getState())
this.setState(store.getState()) // 从store里面重新取改变后的新数据
}
handleBtnClick(){
const action = {
type :'add_todo_item'
}
store.dispatch(action )
}
render() {
return (
<div className='todolist_box'>
<Input placeholder="Basic usage" value = {this.state.inputValue} onChange = {this.handleInputChange}/>
<Button type="primary" onClick={this.handleBtnClick }>添加</Button>
<List
header={<div>Header</div>}
footer={<div>Footer</div>}
bordered
dataSource={this.state.list}
renderItem={item => (<List.Item>{item}</List.Item>)}
/>
</div>
);
}
}
export default TodoList;
reducer.js-即上文中图书馆管理员查询的手册
const defaultState = {
inputValue:"123",
list : [4,5]
}
export default (state = defaultState,action) => { // state 指的是 笔记本里的空数据
console.log(state,action)
if(action.type === 'change_input_value'){
const newState = JSON.parse(JSON.stringify(state)) // 把传递过来的值复制一份
newState.inputValue = action.value
return newState
}
if(action.type==='add_todo_item'){
const newState = JSON.parse(JSON.stringify(state)) // 把传递过来的值复制一份
console.log('add_todo_item 前',newState)
newState.list.push(newState.inputValue)
newState.inputValue = ''
console.log('add_todo_item 后',newState)
return newState
}
return state;
}
他们之间的,如何协调才能实现toDoList呢?看下图
借书人在自己的组件里面,需要写一个action
(发起借书请求),然后通过dispatch
方法,传递到store
里面 ,代码如下
const action = {
type :'add_todo_item'
}
store.dispatch(action )
这里 在action
里面加来个type属性,因为后期在组件里面可能会发起多个action,为来区分,所以加type,通过给type不同的值,进行判断 哪个action
好,现在管理员 store里面得到了组件传递过来的action(我发的借书请求),管理员Store现在要去处理这个借书请求,他就会去查手册reducer
,所以reducer
里面是这样来判断请求的
if(action.type==='add_todo_item'){
const newState = JSON.parse(JSON.stringify(state)) // 把传递过来的值复制一份
console.log('add_todo_item 前',newState)
newState.list.push(newState.inputValue) // 把输入框里的值 放进newState里面
newState.inputValue = '' // 放完后,清空输入框
console.log('add_todo_item 后',newState)
return newState // 最后返回,即官网图里的 reducer =>store
}
现在,管理员store
获取到reducer
返回的借书结果newState
后,他现在要把这个结果告诉借书的人,即 组件 todolist.js
,因为组件 todolist.js
里已经
constructor(props){
super(props)
this.state = store.getState()
store.subscribe(this.handleStorechange) // 监听 store 里面值的变化
}
通过 store.subscribe
来订阅store
里状态的改变,所以现在 组件 todolist.js
里就能获取到 用户在 input
框里输入的值里, 组件 todolist.js
获取到传递过来的值后需要把值动态的展示到页面,如何做呢?
因为 store.subscribe(this.handleStorechange)
调了一个方法 handleStorechange
handleStorechange(){
console.log('handleStorechange changed')
this.setState(store.getState()) // 从store里面重新取改变后的新数据
}
通过 this.setState
动态的双向绑定数据到 view层
下面是 view层显示代码 ,用的antd框架
render() {
return (
<div className='todolist_box'>
<Input placeholder="Basic usage" value = {this.state.inputValue} onChange = {this.handleInputChange}/>
<Button type="primary" onClick={this.handleBtnClick }>添加</Button>
<List
header={<div>Header</div>}
footer={<div>Footer</div>}
bordered
dataSource={this.state.list}
renderItem={item => (<List.Item>{item}</List.Item>)}
/>
</div>
);
}
整个todoList例子的思想图
写完这边博客,感觉自己对redux里的思想理解又更深一层次了,心也静了下来,真好!
更多博客请转移到 作者的个人博客网站
TencentIT的个人博客网站