一、什么是redux
-
1、
redux
的主要作用-
主要作用是方便组件之间的通讯
不使用
redux
的时候组件之间只能通过传值的方式进行通讯,如果组件多了,嵌套多了,通讯方式就只能一层一层的传递,比较麻烦 -
一个项目中只有一个
store
,在根组件中使用上下文的方式传递到整个项目的根组件下
-
-
2、主要的流程
-
components
表示我们的react
组件,在组件中发出一个命令到action
中 -
action
使用dispatch
返回一个带type
类型的对象到reducers
-
reducer
中使用switch
来修改state
的值 - 在组件中订阅仓库的数据
-
二、依赖环境的安装
-
1、使用
npx
创建一个react
项目npx create-react-app [项目名称]
-
2、安装依赖包
npm install redux # 针对于react和redux的连接工具 npm install react-redux
-
3、基本分目录结构
对于小型项目来说,可以不分
store
文件结构,但是对于大项目来说是必须要分的。下面我们先介绍如何单个文件的使用,然后在使用分目录的方式。先创建好目录结构// 项目的src目录下创建一个store的文件夹 ➜ store git:(master) ✗ tree . ├── action-types.js ├── action.js ├── index.js └── reduce.js
三、基本的使用
-
1、在
store/action-types.js
的文件中定义两个常量export const ADD = 'ADD' export const MINUS = 'MINUS'
-
2、在
store/reducer.js
的文件中定义一个reducer
的函数import * as types from './action-types' // 定义初始化的值 let initialState = {number: 0} function reducer (state = initialState , action) { switch (action.type) { case types.ADD: // return {number: state.number + (action.payload || 1)} return {number: state.number + 1} case types.MINUS: return {number: state.number - 1} default: return state } } export default reducer;
-
3、在
store/actions.js
中定义操作的方法import * as types from './action-types' export default { add(payload) { // 如果传递了参数过来就会到payload console.log('点击了', payload) return { type: types.ADD, payload} }, minus(payload) { return {type: types.MINUS,payload} } }
-
4、在根组件中使用
react-redux
将redux
与react
连接起来import { Provider } from 'react-redux' import store from './store' ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') )
-
5、组件中使用
connect
import React, { Component } from 'react' import { connect } from 'react-redux' import action from './../store/actions' class Count1 extends Component { render () { console.log(this.props) return ( <div> <button onClick={this.props.minus}> - </button> {this.props.number} <button onClick={this.props.add}> + </button> </div> ) } } const mapStateToProps = state => { console.log(state) return state } export default connect(mapStateToProps, action)(Count1)
四、多组开发中使用store
来开发
-
1、将
store
文件夹分目录结构➜ store git:(master) ✗ tree . ├── action-types.js ├── actions │ ├── count1.js # 组件count1的action │ └── count2.js ├── index.js └── reduces ├── count1.js # 组件count1的reduces ├── count2.js └── index.js 2 directories, 7 files
-
2、
actions
和reduces
里面的文件和之前的一样的 -
3、
reduces/index.js
的文件是将多个reducer
合并生一个import { combineReducers } from 'redux' import count1 from './count1' import count2 from './count2' const reducers = { count1, count2 } const rootReducer = combineReducers(reducers); export default rootReducer;
-
4、
store/index.js
使用被合并后的reducer
import { createStore } from 'redux' import reducer from './reduces' export default createStore(reducer)
五、使用immutable
来修改状态
-
1、下载安装依赖包npm地址
-
2、在初始化状态的时候使用
immutable
库中的fromJS
包装下... import { fromJS } from 'immutable' // 定义初始化的值 let initialState = fromJS({ number: 10 }); ...
-
3、在
reducer
函数中使用set
和get
来设置新的值import * as types from './../action-types' import { fromJS } from 'immutable' // 定义初始化的值 let initialState = fromJS({ number: 5 }) function reducer (state = initialState , action) { switch (action.type) { case types.ADD: // 如果initialState有多个熟悉的时候,也仅仅会修改number这个属性,不用担心会修改别的属性 return state.set('number', state.get('number') + 1) // return { number: state.number + 1 } case types.MINUS: return state.set('number', state.get('number') - 1) // return { number: state.number - 1 } default: return state } } export default reducer
-
4、在组件
mapStateToProps
中使用const mapStateToProps = state => { console.log(state, state.count1.get('number')) return { number: state.count1.get('number')} }
六、使用redux-immutabale
-
1、为什么要使用
redux-immutable
前面我们介绍了
count1
里面的状态使用了immutable
,是immutable
对象了,但是我们在组件的使用过程中是state.count1.get('number')
前面的state.count1
是普通对象。使用redux-immutable
就可以将state
也变成一个immutable
对象 -
2、安装依赖包
npm install redux-immutable
-
3、在
reducer
中使用// import { combineReducers } from 'redux' // 将原来从redux中的combineReducers改为redux-immutable中的 import { combineReducers } from 'redux-immutable' import count1 from './count1' // import count2 from './count2' const reducers = { count1, // count2 } const rootReducer = combineReducers(reducers) export default rootReducer
-
4、现在
state
也是immutable
对象了,我们要修改组件... const mapStateToProps = state => { // 获取使用 state.getIn(['count1', 'number']); return { number: state.get('count1').get('number')} } export default connect(mapStateToProps, action)(Count1)