index.js中
/*
* @Description:
* @Author: cqj
* @Date: 2021-12-02 10:25:52
* @LastEditTime: 2021-12-03 11:30:38
* @LastEditors: cqj
* @Reference:
*/
import ReactDOM from 'react-dom'
import App from './App.jsx'
//引入提供器 //react-redux写法
import { Provider } from 'react-redux'
import store from './store'
// 定义一个app,来返回Provider组件
const app = (
// 包含在提供器Provider内的组件 无论什么层级 都可以共享仓库数据
<Provider store={store}>
<App />
</Provider>
)
ReactDOM.render(app, document.getElementById('root'))
store/index.js
> 如果想要在浏览器的扩展里面可以看到数据的话,需要加上一串代码
> const store = createStore(reducer,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
/*
* @Description:这里其实是一个store
* @Author: cqj
* @Date: 2021-12-02 10:39:47
* @LastEditTime: 2021-12-03 10:56:08
* @LastEditors: cqj
* @Reference:
*/
import { createStore } from 'redux'
import reducer from './reducer'
//创建store
const store = createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
export default store //默认导出store
App.jsx
import React, { Component } from 'react'
import { addNumCreator }from './store/actionCreators'
// import store from './store' //store已经迁移到顶级组件Provider上面了,所以这里不需要store相关的代码
//引入连接器 (高阶函数)
import {connect} from 'react-redux'
class App extends Component {
//redux写法 改写为react-redux后这些store有关的代码都可以注释掉
// constructor(props) {
// super(props)
//使用store.getState()获取reducer的数据
// this.state = store.getState()
//store的订阅 当状态有更新时,把状态整个赋值一遍
// store.subscribe(this.storeChange.bind(this))
// }
//store发生数据变化的时候订阅
// storeChange() {
// this.setState(store.getState())
// }
render() {
return (
<div>
{/* <h2>{this.state.num}</h2> */}
<h2>{this.props.num}</h2>
{/* <button onClick={ this.addNumFn.bind(this)}>累加</button> */}
<button onClick={ ()=>this.props.addNumFn()}>累加</button>
</div>
)
}
// addNumFn() {
// // this.setState({
// // num:this.state.num+1
// // })
// // const action = {
// // type: ADD_NUM,
// // value:1
// // }
// // store.dispatch(action)
// store.dispatch(addNumCreator(2))
// }
//一种写法
// async addNumFn() {
// let result = await new Promise(resolve => {
// setTimeout(() => {
// resolve(2)
// }, 1000);
// })
// store.dispatch(addNumCreator(result))
// }
}
//状态映射,将state映射为props(再给一份同样的东西 ) 默认得到一个state state 全部改写成props
const mapStateToProps = (state) => {
return {
num:state.num//页面上就可以使用this.props.num访问到num
}
}
//时间派发映射,默认可以获取到 dispatch
const mapDispatchToProps = (dispatch) => {
return {
addNumFn() {
//redux写法 一种写法 相关的store代码也不用引入
// const action = {
// type: ADD_NUM,
// value:1
// }
// store.dispatch(action)
// store.dispatch(addNumCreator(2))
//第二种写法
//react-redux写法
dispatch(addNumCreator(1))
},
//可以写多个
// xx(){}
}
}
// export default connect(状态映射,事件派发映射)(组件名称)
export default connect(mapStateToProps,mapDispatchToProps)(App)
//mapStateToProps全改写成props
reducer.js
reducer做两件事 1.定义默认的状态 2.返回函数
/*
* @Description:
* @Author: cqj
* @Date: 2021-12-02 10:39:55
* @LastEditTime: 2021-12-02 11:14:39
* @LastEditors: cqj
* @Reference:
*/
import { ADD_NUM } from './actionTypes'
//定义默认的状态
const defaultState = {
num: 0
}
//返回函数
//解决报错
//eslint-disable-next-line
export default (state = defaultState, action) => {
let newState = JSON.parse(JSON.stringify(state))
switch (action.type) {
case ADD_NUM:
newState.num += action.value
break;
default:
break;
}
return newState
}
actionCreator.js
用来产生action的
/*
* @Description:
* @Author: cqj
* @Date: 2021-12-02 10:58:45
* @LastEditTime: 2021-12-02 18:02:15
* @LastEditors: cqj
* @Reference:
*/
import { ADD_NUM } from "./actionTypes";
//累加
export const addNumCreator = (num) => {
return {
type: ADD_NUM,
value: num
}
}
actionsTypes.js
实际开发中,我们会写很多个action,其中的type就会出现很多个,因为每个action中必带一个type,这样就导致我们要找一个bug会比较难,而且不可复用。所以我们将action的type抽离出来,成为 actionTypes.js 文件
/*
* @Description:
* @Author: cqj
* @Date: 2021-12-02 10:56:14
* @LastEditTime: 2021-12-02 10:56:15
* @LastEditors: cqj
* @Reference:
*/
export const ADD_NUM = 'addNum'