React补完计划之Redux篇

1,071 阅读4分钟

我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情

React补完计划第二篇 书接上回,React简易上手指南

1.认识Redux

React是一个轻量级的视图层框架,组件之间的通讯十分繁琐。

项目开发中,需要视图层框架和数据层框架,Redux是现在React生态中最好的数据层框架。

对比一下Vue全家桶,Vuex只支持在Vue中使用。但是,Redux并不是只能在React中使用。

🚀Redux中文官网传送门

如下图所示,Redux 简化了状态管理。数据存放在数据仓库 store 中,统一管理。

clipboard.png

2.Redux工作流程讲解

clipboard1.png

应用的整体全局状态以对象树的方式存放于单个 store

唯一改变状态树(state tree)的方法是创建 action,一个描述发生了什么的对象,并将其 dispatch 给 store

要指定状态树如何响应 action 来进行更新,你可以编写纯 reducer 函数,这些函数根据旧 stateaction 来计算新 state。

clipboard2.png

打个比方

React Components 相对于借书的人;

Action Creator 相当于图书管理员;

Store 相当于图书馆;

Reducers 相当于图书管理软件;

借书先找到图书管理员,图书管理员在图书馆里,通过图书管理软件,找到图书在哪里,并且借出。

🚀具体解释,详见Redux中文官网之词汇表

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界面

Ant Design官网传送门

编写组件

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;

页面效果

clipboard111.png

5.创建Redux中的仓库:store 和 reducer

安装Redux

npm install redux --save

clipboard3.png

新建 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文件。

redux-devtools工具Github地址

正如 Github地址上使用说明,需要在store仓库创建时,增加配置。

 const store = createStore(
   reducer, /* preloadedState, */
+  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
 );

重启浏览器,打开控制台,tab页上有一个Redux,表示配置成功。

如下图所示,可以看到Redux的一些相关信息,譬如state状态。

clipboardaaa.png

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
  }

clipboardxxx.png

最后的话

以上,如果对你有用的话,不妨点赞收藏关注一下,谢谢 🙏