接着上个页面实现按钮点击
在上个页面加入按钮,实现点击按钮,实现App组件内的数据更新
import React, { Component } from 'react'
import store from './store'
import Com1 from './components/com1'
export default class App extends Component {
constructor(){
super()
// 获取store里面的值,更新页面里面的count
this.state = store.getState()
// 设置监听函数,当store里面的值发生改变会触发这个函数
// store.subscribe(this.listenStore)
}
handleClick(){
const action={
type:'add_count',
value:1
}
store.dispatch(action)
}
// listenStore = ()=>{
// 当点击按钮,在改变页面里count值的时候,会触发这个函数执行,那么就可以在这里进一步触发页面的更新
// console.log(1)
// this.setState ( store.getState())
// }
render() {
return (
<div>
this is App
<br />
store里面的数据---{'>'}{this.state.count}
<button onClick={this.handleClick}>+</button>
<Com1></Com1>
</div>
)
}
}
在App组件内点击按钮,传递到src/store/reducer.js,我们可以打印传递过来的action的内容:
// 定义好数据
const defaultState = {// 类似于vue的state
count:1
}
export default (state = defaultState,action)=>{
console.log(action)
// 对进来的请求进行判断,分开处理
// if(action.type==='add_count'){
// // 对defaultState进行深拷贝,处理完成后回溯回去
// let newState = JSON.parse(JSON.stringify(state))
// newState.count += action.value
// console.log(newState)
// return newState
// }
return state
}
可以看到从App.js 通过store.dispatch传递过来的action的内容包括类型和数据value,我们可以拿到value对store里面的defaultState进行一定的处理
export default (state = defaultState,action)=>{
// console.log(action)
// 对进来的请求进行判断,分开处理
if(action.type==='add_count'){
// 对defaultState进行深拷贝,处理完成后回溯回去
let newState = JSON.parse(JSON.stringify(state))
newState.count += action.value
console.log(newState)
return newState
}
return state
}
可以看到此时的value已经更新到2,只是暂时还没有更新到页面里面去
这是我们回到App.js,可以在App.js中的原型constructor添加监听函数:
constructor(){
super()
// 获取store里面的值,更新页面里面的count
this.state = store.getState()
// 设置监听函数,当store里面的值发生改变会触发这个函数
store.subscribe(this.listenStore)
}
....
listenStore = ()=>{
// 当点击按钮,在改变页面里count值的时候,会触发这个函数执行,那么就可以在这里进一步触发页面的更新
console.log(1)
// this.setState ( store.getState())
}
我们可以看到只要当App组件内的count发生变化就会触发listen函数的执行,那么我们只需要在listen函数内部实现页面数据的同步即可:
listenStore = ()=>{
// 当点击按钮,在改变页面里count值的时候,会触发这个函数执行,那么就可以在这里进一步触发页面的更新
console.log(1)
this.setState ( store.getState())
}
此时的App组件的count会随着数据的改变而改变,而Com1组件内的内容是不会发生改变的,这里就是与Vuex最大的变化了。
在Vuex里面,假如一个组件的触发改变了Vuex内部的数据,那么其他利用Store里面数据的地方也会发生改变,而redux只有在使用了(监听函数store.subscribe(this.你定义的函数名)+你定义的函数)去更新数据,才会在页面中有相应的改变,这也是react最大的魅力所在。
例如我们也想Com1可以随着store里面的count改变而改变,那么只需要在Com1里面利用监听函数就可以了:
import React, { Component } from 'react'
import store from '../store/index'
export default class com1 extends Component {
constructor(){
super()
this.state = store.getState()
store.subscribe(this.Com1Store)
}
Com1Store = ()=>{
this.setState(store.getState())
}
render() {
return (
<div>
this is Com1
<br />
<span>Com1 使用redux里面的数据---{'>'}{this.state.count}</span>
</div>
)
}
}
而且react没有太多封装的方法,大多都接近于原生,所以可以大大锻炼你对原生js的理解哦,不过最大的缺陷就是它的数据流是单向的,不像vue的双向数据绑定,所以使用它需要自己通过this.setState()方法来将它的数据同步回溯回去。
PS:
redux可以用到的google插件 react-devtools:
要出现下面的界面,记住在store的index.js添加:
window.REDUX_DEVTOOLS_EXTENSION && window.REDUX_DEVTOOLS_EXTENSION()