一、创建项目+安装redux
Redux三大原则:
唯一数据源
保持只读状态
数据改变只能通过纯函数来执行
npm i create-react-app todosth
npm i redux
二、项目基本结构
将src 下的所有文件删除,创建index.js和Add.js
src>index.js
import React from 'react'
import {createRoot} from 'react-dom/client'
import Add from './Add'
const root = document.getElementById('root');
root.render(
<div>
<Add/>
</div>
)
src>Add.js
import React, {Compoent} from 'react'
export default class Add extends Component{
constructor(){
super()
this.state={
num:0
}
this.addClick = this.addClick.bind(this)
}
render(){
return(
<div>
<div>num: {this.state.num}</div>
<button onClick={this.addClick}></button>
</div>
)
}
addClick(){
//state的值只能通过setState修改
this,setState({
num:this.state.num+1
})
}
}
三、创建仓库
src目录下创建store文件夹,作为仓库使用。在其中新建 index.js 与 reducer.js ,分别写:
src>store>index.js
import { createStore } from 'redux' //引入createStore对象
import reducer from './reducer' //引入reducer
const store = createStore(reducer) //创建储存库
export default store
src>store>reducer,js
const defaultState = {
num:0
}
//导出一个函数,用于返回state
export default (state = defaultState, action)=>{
return state
}
这里的state 表示原始仓库的状态;
action 表示新传递的状态。
以上代码把数据存在了仓库里面,将Add.js进行修改,数据从仓库中取,并设置订阅。
Add.js中
import React, { Component } from 'react'
export default class Add extends Component{
constructor(props){
super(props)
this.state = store.getState() //获取仓库状态(初始)
store.subscribe(this.storeChange.bind(this)) //订阅仓库的变化
}
render(){
return(
<div>
<div>num: this.state.num</div>
<button>num+1</button>
</div>)
}
storeChange(){
this.setState(store.getState) //订阅
}
}
四、累加事件
Add.js
import React, { Component } from 'react'
export default class Add extends Component{
constructor(props){
super(props)
this.state = store.getState() //获取仓库状态(初始)
store.subscribe(this.storeChange.bind(this)) //订阅仓库的变化
this.AddFn=this.AddFn.bind(this)
}
render(){
return(
<div>
<div>num: this.state.num</div>
<button onClick={this.AddFn}>num+1</button>
</div>)
}
storeChange(){
this.setState(store.getState) //订阅
}
AddFn(){
const action ={
type:'add_fn',
value:1
}
store.dispatch(action)
}
}
reducer.js
const defaultState = {
num:0
}
//导出(一开始的时候,state作为形参,一开始没有值,所以让他等于defaultState)
export default (state = defaultState, action) =>{
//对原本的state做一次深拷贝。
//reducer只能接收state,不能直接对它进行改变
var newState = JSON.parse(JSON.stringify(state))
//通过判断action的type,确定是否需要修改
switch (action.type) {
case 'add_fn':
newState.num += action.value;
break;
default:
break;
}
return newState;
}