const {createStore} = require("redux")
//初始化state
const defaultState = {
name:"root",
counter:100
}
//定义reducer函数纯函数 2个参数 1为目前store中的值 2.action
function reducer(state = defaultState,action){
// console.log(state,"------",action);
// if(action.type === "change_name"){
// return {...state,name: action.name}
// }else if(action.type === "change_num"){
// return {...state,counter:state.counter+action.num}
// }
//有更新返回更新的State ,无 返回初始state
// return state
//-------------------------------------------------------
switch (action.type) {
case "change_name":
return {...state, name:action.name}
break;
case "change_num":
return {...state, counter:state.counter+action.num}
default:
return state
}
}
const store = createStore(reducer)
//导出
module.exports = store
const store = require("./store");
console.log(store.getState())
//
// store.subscribe(()=>{
// console.log("订阅数据的变化",store.getState());
// })
const unsubscribe =store.subscribe(()=>{
console.log("订阅数据的变化",store.getState());
})
//修改store 必须用action
const nameAction = {type:"change_name",name:"kobe"}
store.dispatch(nameAction)
const name1Action = {type:"change_name",name:"lilei"}
store.dispatch(name1Action)
const counterAction ={type:"change_num",num:10}
store.dispatch(counterAction)
//取消订阅
unsubscribe()
store.dispatch({type:"change_name",name:"kobe"})
代码重构优化:
1.将 派发的action生成过分,分装到一个函数(actionnCreators)中。
2.将定义actionnCreators函数放到一个独立的文件中(actionnCreators.js)
3.将常量(chang_name...)抽取到一个独立的constants文件这种
4.将reducer函数以及state设置默认值放到reducer.js中
APP.JSX
import React, {PureComponent } from 'react'
import Home from './pages/home'
import Profile from './pages/profile'
import './style.css'
import store from './store/index'
import About from './pages/About'
export class App extends PureComponent {
constructor(){
super()
this.state ={
counter:store.getState().counter //初始化
}
}
componentDidMount(){
// console.log(store.getState());
store.subscribe(()=>{
const state = store.getState()
this.setState({
counter:state.counter
})
})
}
render() {
const {counter} = this.state
return (
<div>
<h2>App counter: {counter}</h2>
<div className='pages'>
<Home/>
<Profile/>
<About/>
</div>
</div>
)
}
}
export default App
pages
//----------Home ----------------------
import React, { PureComponent } from 'react'
import store from '../store/index'
import { addNumAction } from '../store/actionnCreators'
export class Home extends PureComponent {
constructor(){
super()
this.state ={
counter:store.getState().counter //初始化
}
}
componentDidMount(){
// console.log(store.getState());
store.subscribe(()=>{
const state = store.getState()
this.setState({
counter:state.counter
})
})
}
addNum(num){
store.dispatch(addNumAction(num))
}
render() {
const {counter} = this.state
return (
<div>
<p>counter:{counter}</p>
<button onClick={e=>this.addNum(1)}>+1 </button>
<button onClick={e=>this.addNum(5)}>+5 </button>
<button onClick={e=>this.addNum(10)}>+10</button>
</div>
)
}
}
export default Home
//--------------------------profile------------------------
import React, { PureComponent } from 'react'
import store from '../store/index'
import { subNumAction } from '../store/actionnCreators'
export class Profile extends PureComponent {
constructor(){
super()
this.state ={
counter:store.getState().counter //初始化
}
}
componentDidMount(){
// console.log(store.getState()); //订阅
store.subscribe(()=>{
const state = store.getState()
this.setState({
counter:state.counter
})
})
}
subNum(num){
store.dispatch(subNumAction(num))
}
render() {
const {counter} = this.state
return (
<div>
<p>counter: {counter}</p>
<button onClick={e=>this.subNum(1)}>-1 </button>
<button onClick={e=>this.subNum(5)}>-5 </button>
<button onClick={e=>this.subNum(10)}>-10</button>
</div>
)
}
}
export default Profile
store
//----------------------创建store--------------
import { createStore } from "redux";
import reducer from "../store/recuder.js";
const store = createStore(reducer)
export default store
//-----------------初始化 ------- 创建reducer() --------
import {ADD_NUM,SUB_NUM} from './constants'
const defaultState = {
counter:100
}
function reducer(state = defaultState,action){
switch(action.type){
case ADD_NUM:
return {...state,counter:state.counter+action.num}
case SUB_NUM:
return {...state,counter:state.counter-action.num}
default:
return defaultState
}
}
export default reducer
//----------------创建Action 更改数据
import * as actType from "./constants"
export const addNumAction = num=>({
type: actType.ADD_NUM,
num
})
export const subNumAction = num=>({
type: actType.SUB_NUM,
num
})
//-------------------常量----------------
export const ADD_NUM = "add_num"
export const SUB_NUM = "sub_num"
redux的三大原则:
单一数据源
1.整个程序的state存储在一个object tree中,并且这个object tree存储在一个store中
2.没有限制不让创建多个store,但是不利于数据维护。
3.单一的数据源让整个应用程序state变的方便维护追踪修改。
state是只读的
1.唯一修改方式是:触发action
2.确保View或网络请求不能直接修改
3.保证所有修改都是同一集中化处理,并且按照严格的顺序 不需要担心 (竞态) 的问题
使用纯函数来进行修改
1.通过reducer将 state和 action联系在一起,返回一个新的state
2.复杂应用程序 将reducer拆分成多个小的reducerds,分别操作不同的state tree
3.所有的reducer()必须是纯函数,不能产生副作用。