注意:以下每一步是按照redux由易到难的顺序逐步进行的,从初步使用到react与redux的组合使用以及解耦的顺序来的
安装redux
npm install redux --save
1、redux的简单使用
1、新建store
2、获取状态
3、派发事件
下边代码简单的演示此过程
在src下新建index.js,在index中编写
import {createStore} from 'redux'
//1、新建store
//通过reducer建立
//根据老的state和action 生成新的state
function counter(state=0,action){
switch(action.type){
case 'addGun':
return state+1
case 'removeGun':
return state-1
default:
return 10
}
}
//1、新建store
const store = createStore(counter)
//2、获取状态
const init = store.getState()
function listener(){
const current = store.getState()
console.log(`现在的个数${current}`);
}
//每次派发事件之后,都会调用,进而获取状态
store.subscribe(listener)
//3、派发事件
store.dispatch({type:'addGun'})
store.dispatch({type:'addGun'})
store.dispatch({type:'removeGun'})
输出:
现在的个数11
现在的个数12
现在的个数11
2、react与redux组合使用(手动连接)
- 把store.dispatch方法传递给组件,内部可以调用修改状态
- subscribe订阅render函数,每次修改都重新渲染
- redux相关的内容,移动到单独的文件index.redux.js单独管理
- npm install redux-thunk --save 解决异步请求的问题
使用applyMiddleware开启thunk中间件
在src下新建App.js、index.redux.js
在index.js中负责页面结构的组建,store的建立
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'
import { createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {counter} from './index.redux'
import {addGun,removeGun,addGunAsync} from './index.redux'
//applyMiddleware可以使用异步操作
const store = createStore(counter,applyMiddleware(thunk))
function render(){
ReactDom.render(<App store={store} addGun={addGun} removeGun={removeGun} addGunAsync={addGunAsync}/>,document.getElementById('root'))
}
render()
//监听状态的变化,每次重新渲染组件
store.subscribe(render)
在App.js中完成组件内容的编写、页面的渲染以及相关事件的派发
import React from 'react'
class App extends React.Component{
// constructor(props){
// super(props)
// }
render(){
//接收从父组件index.js中传过来的store
const store = this.props.store
//获取机枪数量状态的变化
const num = store.getState()
//通过组件传递action,降低耦合度
const addGun = this.props.addGun
const removeGun = this.props.removeGun
const addGunAsync = this.props.addGunAsync
return(
<div>
<h2>现在有机枪{num}</h2>
{/* 当点击按钮时执行事件的派发,即调用action */}
<button onClick={()=>store.dispatch(addGun())}>申请武器</button>
<button onClick={()=>store.dispatch(removeGun())}>回收武器</button>
<button onClick={()=>store.dispatch(addGunAsync())}>延迟回收武器</button>
</div>
)
}
}
export default App
index.redux.js 中负责store中对状态变化的处理、action事件的编写
const ADD_GUN = 'addGun'
const REMOVE_GUN = 'removeGun'
//store
export function counter(state=0,action){
//当action被调用执行后,会到此处进行判断,执行状态的变化
switch(action.type){
case 'addGun':
return state+1
case 'removeGun':
return state-1
default:
return 10
}
}
//action
export function addGun(){
return {type:ADD_GUN}
}
export function removeGun(){
return {type:REMOVE_GUN}
}
export function addGunAsync(){
return dispatch=>{
setTimeout(()=>{
dispatch(addGun())
},2000)
}
}
此种方法的弊端:如果有多个组件深层次传递store属性,就会特别繁琐,容易出错,接下来我们就解决这个问题
3、redux使用的解耦(react与redux自动连接)
解决第二步的问题,我们安装插件
npm install react-redux --save 用于自动连接react与redux,不需要再调用subscribe方法
- Provider 包裹在组件最外层,传入store
- Connect负责从外部获取组件所需要的参数
- Connect使用装饰器的方式写
装饰器的安装配置
参考文章
在index.js中负责页面结构的组建,store的建立
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'
import { createStore, applyMiddleware,compose} from 'redux'
import {Provider} from 'react-redux'
import thunk from 'redux-thunk'
import {counter} from './index.redux'
const store = createStore(counter,compose(
applyMiddleware(thunk),
//调用chrome中的redux插件
window.devToolsExtension?window.devToolsExtension():f=>f
))
ReactDom.render(
<Provider store={store}>
<App />
</Provider>,document.getElementById('root')
)
在App.js中完成组件内容的编写、页面的渲染以及相关事件的派发
import React from 'react'
import {connect} from 'react-redux'
import {addGun,removeGun,addGunAsync} from './index.redux'
@connect(
//需要的state属性放到props中
state=>({num:state}),
//需要的方法,放到props中,自动dispatch
{addGun,removeGun,addGunAsync}
)
class App extends React.Component{
render(){
return(
<div>
<h2>现在有机枪{this.props.num}</h2>
{/* 当点击按钮时执行事件的派发,即调用action */}
<button onClick={this.props.addGun}>申请武器</button>
<button onClick={this.props.removeGun}>回收武器</button>
<button onClick={this.props.addGunAsync}>延迟申请武器</button>
</div>
)
}
}
export default App
index.redux.js 中负责store中对状态变化的处理、action事件的编写
const ADD_GUN = 'addGun'
const REMOVE_GUN = 'removeGun'
//store
export function counter(state=0,action){
//当action被调用执行后,会到此处进行判断,执行状态的变化
switch(action.type){
case 'addGun':
return state+1
case 'removeGun':
return state-1
default:
return 10
}
}
//action
export function addGun(){
return {type:ADD_GUN}
}
export function removeGun(){
return {type:REMOVE_GUN}
}
export function addGunAsync(){
return dispatch=>{
setTimeout(()=>{
dispatch(addGun())
},2000)
}
}