我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情
React补完计划第二篇 书接上回,React简易上手指南
1.认识Redux
React是一个轻量级的视图层框架,组件之间的通讯十分繁琐。
项目开发中,需要视图层框架和数据层框架,Redux是现在React生态中最好的数据层框架。
对比一下Vue全家桶,Vuex只支持在Vue中使用。但是,Redux并不是只能在React中使用。
如下图所示,Redux 简化了状态管理。数据存放在数据仓库 store 中,统一管理。
2.Redux工作流程讲解
应用的整体全局状态以对象树的方式存放于单个 store。
唯一改变状态树(state tree)的方法是创建 action,一个描述发生了什么的对象,并将其 dispatch 给 store。
要指定状态树如何响应 action 来进行更新,你可以编写纯 reducer 函数,这些函数根据旧 state 和 action 来计算新 state。
打个比方
React Components 相对于借书的人;
Action Creator 相当于图书管理员;
Store 相当于图书馆;
Reducers 相当于图书管理软件;
借书先找到图书管理员,图书管理员在图书馆里,通过图书管理软件,找到图书在哪里,并且借出。
3.开发环境初始化
安装react脚手架
npm install -g create-react-app
创建项目
create-react-app redux-demo
新建TodoList.js文件
import React, { Component } from 'react';
class TodoList extends Component {
state = {}
render() {
return (
<div>Halo Girl</div>
);
}
}
export default TodoList;
vscode开发工具,安装 Simple React Snippets 插件,可以快捷生成一些代码。
快捷生成
快捷键 imrc
import React, { Component } from 'react';
快捷键 ccc
class extends Component {
constructor(props) {
super(props);
}
state = { }
render() {
return ( );
}
}
export default ;
安装 Ant Design
npm install antd --save
4.使用Ant Design 制作UI界面
编写组件
import React, { Component } from 'react';
import 'antd/dist/antd.css'
import { Input, Button, List } from 'antd';
const data = [
'malena morgan',
'mila',
'lina',
'luna',
]
class TodoList extends Component {
state = {}
render() {
return (
<div>
<div style={{ margin: '10px' }}>
<Input
placeholder='Write Something'
style={{ width: '250px', marginRight: '10px' }} />
<Button type='primary'>增加</Button>
</div>
<div style={{ margin: '10px', width: '300px' }}>
<List
bordered
dataSource={data}
renderItem={item =>(<List.Item>{item}</List.Item>)} />
</div>
</div>
);
}
}
export default TodoList;
页面效果
5.创建Redux中的仓库:store 和 reducer
安装Redux
npm install redux --save
新建 src\store\index.js 文件
import { createStore } from "redux";
import reducer from './reducer';
const store = createStore(reducer)
export default store
新建 src\store\reducer.js 文件
const defaultState = {
inputValue: 'Write Something',
list: [
'malena morgan',
'mila',
'lina',
'luna',
]
}
export default (state = defaultState, action) => {
return state
}
修改 src\TodoList.js 文件,通过 store.getState() 取数据
import React, { Component } from 'react';
import 'antd/dist/antd.css'
import { Input, Button, List } from 'antd';
import store from './store';
class TodoList extends Component {
constructor(props){
super(props)
console.log(store.getState());
this.state = store.getState()
}
render() {
return (
<div>
<div style={{ margin: '10px' }}>
<Input
placeholder={this.state.inputValue}
style={{ width: '250px', marginRight: '10px' }} />
<Button type='primary'>增加</Button>
</div>
<div style={{ margin: '10px', width: '300px' }}>
<List
bordered
dataSource={this.state.list}
renderItem={item =>(<List.Item>{item}</List.Item>)} />
</div>
</div>
);
}
}
export default TodoList;
6.Redux_Dev_Tools的安装
百度盘下载地址: 链接:pan.baidu.com/s/1vrKkP2Wy… 提取码:1234
Redux DevTools下载后,在浏览器扩展程序里,加载已解压的ctx文件。
正如 Github地址上使用说明,需要在store仓库创建时,增加配置。
const store = createStore(
reducer, /* preloadedState, */
+ window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
重启浏览器,打开控制台,tab页上有一个Redux,表示配置成功。
如下图所示,可以看到Redux的一些相关信息,譬如state状态。
vscode开发工具,安装Redux DevTools插件,更加简单方便。
7.通过Input体验Redux的流程
修改 src\store\reducer.js 文件
Reducer里只能接受state,不能改变state,通过一个中间值来接收并返回
const defaultState = {
inputValue: 'Write Something',
list: [
'malena morgan',
'mila',
'lina',
'luna',
]
}
export default (state = defaultState, action) => {
console.log(state)
console.log(action)
// Reducer里只能接受state,不能改变state
if (action.type == 'changeInput') {
let newState = JSON.parse(JSON.stringify(state))
newState.inputValue = action.value
return newState
}
return state
}
修改 src\TodoList.js 文件
在 changeInputValue 事件中,新增action和 store.dispatch(action) 方法;
dispatch 方法来触发,它将 action 发送到 reducer 函数,然后 reducer 函数根据匹配规则进行状态的更新。
changeInputValue = (e) => {
const action = {
type: 'changeInput',
value: e.target.value
}
store.dispatch(action)
}
Redux中的state改变后,页面的state并不会一起改变。需要通过subscribe订阅改变state的值。
subscribe订阅: 当store中数据发生变化就会更新数据
//subscribe 当store中数据发生变化就会更新数据
this.storeChange = this.storeChange.bind(this)
store.subscribe(this.storeChange)
storeChange = (e) => {
this.setState(store.getState())
}
import React, { Component } from 'react';
import 'antd/dist/antd.css'
import { Input, Button, List } from 'antd';
import store from './store';
class TodoList extends Component {
constructor(props) {
super(props)
console.log(store.getState());
this.state = store.getState()
//subscribe 当store中数据发生变化就会更新数据
this.storeChange = this.storeChange.bind(this)
store.subscribe(this.storeChange)
}
changeInputValue = (e) => {
const action = {
type: 'changeInput',
value: e.target.value
}
store.dispatch(action)
}
storeChange = (e) => {
this.setState(store.getState())
}
render() {
return (
<div>
<div style={{ margin: '10px' }}>
<Input
placeholder={this.state.inputValue}
onChange={this.changeInputValue}
value={this.state.inputValue}
style={{ width: '250px', marginRight: '10px' }} />
<Button type='primary'>增加</Button>
</div>
<div style={{ margin: '10px', width: '300px' }}>
<List
bordered
dataSource={this.state.list}
renderItem={item => (<List.Item>{item}</List.Item>)} />
</div>
</div>
);
}
}
export default TodoList;
8.Redux制作ToDoList列表
修改 src\TodoList.js 文件
“增加”的按钮上,增加一个点击事件
clickBtn = (e) => {
console.log('orzr3');
const action = { type: 'addItem' }
store.dispatch(action)
}
修改 src\store\reducer.js 文件
if (action.type == 'addItem') {
let newState = JSON.parse(JSON.stringify(state))
newState.list.push(newState.inputValue)
newState.inputValue = ''
return newState
}
最后的话
以上,如果对你有用的话,不妨点赞收藏关注一下,谢谢 🙏