说到底,redux和react只是一个工具而已,想要真正用好的话,理解到思想就可以了
这篇文章并不严谨,纯粹是个人的看法,写的时候也仅凭印象写的,所以参考请谨慎
react和redux
实际上react与redux没有太大的关系,怎么说都好,react只是属于mvc中的v,说到底也只是属于视图层,即便他拥有state和props等的数据流,也不代表他的主要职责就是处理数据,而相应的redux则是一种思想,实际上只需要纯js就可以轻松完成redux的流程控制
那么也就是说,react完全可以依赖于其他框架或者是balabala什么玩意的都没有问题,只是redux对于react而言是一个非常不错的数据管理方式,而且由于react-redux封装了许多有用的方法使得react对自己组件的数据流更加简便,所以还是可以推荐使用的
不过redux在某种程度上会加深react本身的复杂性,所以如果不是一些需要复杂数据流的大型应用的话,使用redux是完全没有必要的,而且就算是构建大型应用也有许多不错的框架可以使用,所以使用redux请谨慎
<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>
...
<script>
var initialState ={
color: 'red'
}
function color(state, action){
if(typeof state === 'undefined') {
return initialState
}
switch (action.type){
case 'RED' :
return { color: 'red' }
case 'GREEN' :
return { color: 'green'}
case 'TOGGLE' :
return state.color === 'red'?{color:'green'}:{color:'red'}
default :
return state
}
}
var store = Redux.createStore(color)
var colorEl = document.getElementById('colorEl')
function renderValue() {
colorEl.style.color = store.getState().color
}
renderValue()
store.subscribe(renderValue)
document.getElementById('red').addEventListener('click', function(){
store.dispatch({
type: 'RED'
})
console.log(store.getState())
})
document.getElementById('green').addEventListener('click', function(){
store.dispatch({
type: 'GREEN'
})
console.log(store.getState())
})
document.getElementById('toggle').addEventListener('click', function(){
store.dispatch({
type: 'TOGGLE'
})
console.log(store.getState())
})
</script>
react-redux
虽然react和redux不是必须相互依赖的,但是两者结合起来却可以完成一些挺不错的工作,redux讲究的是通过用户操作然后redux就调用(dispatch)action,而reducer则通过接收到的action和旧的state返回一个新的state,这当中的一系列的操作都是由顶层的store管理的,这store有着不少state,而这react-redux之所以可以走在一起,和这个机制也有着很大关联
如果说每个组件就是一个state,然后只需要一个store来管理就可以了,哪个组件需要哪个state的话,那就直接让它来store拿就好了,相应的,如果哪个组件需要改变state状态的话,那就让它去dispatch便好了
而react-redux这个库,便是封装了这些方法,让我们可以很简单的利用这些api来管理我们的项目
在这里,redux实际上是做了一个数据流管理,从用户操作dispatch action,reducer接受到action以后就更新当前状态,这时候应用中所有state都会得到更新,换句话说,redux解决了数据流向和更新问题
所有的state都来源于store,如果想要更新自己的从store中获取的state的话就必须经过action,至于组件自身的state则是来自组件自身或者是用户输入的,所以这里的state也可以通过aciton传递给store再由store来传递回自己或是传递给其他组件
简单的流程
store=>component state&this.props state =>store
怎么让react和redux联系起来?
很简单,最重要的函数有三个
-
mapStateToProps
,这个是让组件从store获取state的函数
function mapStateToProps(state) {
return {
user: state.user /*从store中拿来todo这个对象*/
}
}
-
mapDispatchToProps
,这个是让组件拿到action的函数
function mapDispatchToProps(dispatch){
return bindActionCreators({
handleSign: addUserAction
}, dispatch)
}
- 最后一个则是将这两个函数跟组件一起送到redux流程中的函数,
connect
let Register = connect(
mapStateToProps,
mapDispatchToProps
)(rootRegister)
那么store从哪里来?又该怎么管理?
这里也很简单,react-redux提供了很好的方法让我们管理这个Store,只需要两步轻松完成
- 创建store
- 用react-redux提供的Provider标签把你的app包起来
var initState = { /*先初始化state*/
user: {
list: []
}
}
const logger = createLogger()/*由redux-logger提供的一个日志管理中间件*/
const createStoreWithMiddleware = applyMiddleware(/*这里是通过中间件创建store*/
thunk,
logger
)(createStore)/*这里的createStore是由redux提供的一个方法,用来创建store*/
/*需要注意的是applyMiddleware是由redux提供的一个中间件,这里面包含许多有趣的知识,有兴趣的可以去查阅下资料*/
let store = createStoreWithMiddleware(reducer, initState)/*传入我们的reducer和初始state就可以了*/
对了,上边还有一点,react组件要怎么使用来自redux的state,又该怎么交回给redux?
这里是一个react组件的代码,伴有注释,应该很容易理解
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { addUserAction } from '../actions/action.js'
class rootRegister extends Component {
constructor(props) {
super(props)
var defaultState = {
user: {
username: "",
password: "",
passwordagain: ""
}
}
this.state = defaultState /*每个组件都该有自己的state,要么是从mapStateToProps上边拿到,要么就是自己初始化*/
}
componentWillMount(){
}
onTextChange(key) { /*监听组件并且反馈回state*/
return e => {
var user = this.state.user
user[key] = e.target.value
this.setState({ user })
//console.log(user)
}
}
handleClick(user) {
console.log(user)
const { handleSign } = this.props /*这里就是由mapDispatchToProps中提供的action方法*/
if(user.password!=user.passwordagain){
console.log('not same password')
return false
}else{
handleSign(user)
}
}
render(){
var user = this.state.user
return (
<div>
<p>Register T_T</p>
<input value={user.username} type="text" onChange={this.onTextChange('username').bind(this)} placeholder="Username" /><br/>
<input value={user.password} type="password" onChange={this.onTextChange('password').bind(this)} placeholder="password" /><br/>
<input value={user.passwordagain} type="password" onChange={this.onTextChange('passwordagain').bind(this)} placeholder="passwordagain" /><br/>
<span onClick={this.handleClick.bind(this, user)}>signin</span>
</div>
)
}
}
function mapStateToProps(state) {
return {}
}
function mapDispatchToProps(dispatch){
return bindActionCreators({
handleSign: addUserAction
}, dispatch)
}
let Register = connect(
mapStateToProps,
mapDispatchToProps
)(rootRegister)
export default Register
至此,react和redux便是真正的联系起来了