React-Redux
React-Redux is different from Redux which is build from React, while Redux is a plugin and you can use it in Vue also.
在index js 中设置provider 传递store给App下所有子组件
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import store from './components/redux/store.jsx'
import {Provider} from 'react-redux'
ReactDOM.render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root')
)在components下建containers和redux文件如下,也可把reducer再汇总成一个,只暴露index-reducer

在store中引入reducer,使用中间件
//引入createStore,专门用于创建redux中最为核心的store对象
import {createStore,applyMiddleware,combineReducers} from 'redux'
//引入reducer
import addReducer from './reducers/add-reducer'
import personReducer from './reducers/person-reducer'
//引入redux-thunk,用于支持异步action
import thunk from 'redux-thunk'
const allReducers = combineReducers({
adds:addReducer,
persons:personReducer
})
//暴露store
export default createStore(allReducers,applyMiddleware(thunk))在action中 pass type and data to reducer
export const createAddPersonAction =(personObj)=>({type:'addPerson',data:personObj})export function createIncrementAction(data){
return {type:'increment',data}
}
export const createDecrementAction = data =>({type:'decrement',data})
export const createIncrementAsyncAction = (data,syncTime)=> {
return (dispatch)=>{
setTimeout(()=>{
dispatch(createIncrementAction(data))
},syncTime)
}
}在reducer接收previous value 和action,action中有type和打他,再加工数据
const init = [{id:'001',name:'zhang',age:10}]
export default function personReducer(pre,action){
const {type,data} = action
switch (type) {
case 'addPerson' :
return [data,...pre]
//return pre.unshift(data) not working
default:
return init
}
}在 container里通过connect中state接到数据,再通过props传递给UI
In Person.jsx container
import React, { Component } from 'react'
import {connect} from 'react-redux'
import {createAddPersonAction} from '../redux/actions/person-action'
class Person extends Component {
addPerson=()=>{
const name = this.nameNode.value
const age = this.ageNode.value
const personObj = {id:Date.now(),name,age}
this.props.addPersons(personObj)
}
render() {
return (
<div>
<h1>Up: {this.props.sum}</h1>
<input ref={c=>{this.nameNode = c}} type="text" placeholder='name' />
<input ref={c=>{this.ageNode=c}} type="text" placeholder='age' />
<button onClick={this.addPerson}>add</button>
<ul>
{this.props.people.map(p=>{
return <li key={p.id}>
{p.name} --- {p.age}
</li>
})}
</ul>
</div>
)
}
}
export default connect(
state =>({people:state.persons,sum:state.adds}),{
addPersons:createAddPersonAction
}
)(Person)In Add.jsx container
import React, { Component } from 'react'
import {connect} from 'react-redux'
import { createIncrementAction,createDecrementAction,createIncrementAsyncAction} from '../redux/actions/add-action'
class Add extends Component {
increment=()=>{
const{value} = this.selectNum
this.props.add(value*1)
}
decrement=()=>{
const{value} = this.selectNum
this.props.minus(value*1)
}
incrementAsync=()=>{
const {value} = this.selectNum
this.props.addAsync(value*1,500)
}
render() {
return (
<div>
<h1>Total is {this.props.total}</h1>
<h1>Up is {this.props.people.length}</h1>
<select ref={c=>{this.selectNum=c}}>
<option value='1'>1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button onClick={this.increment}>add</button>
<button onClick={this.decrement}>minuse</button>
<button onClick={this.incrementAsync}>asyncronus add</button>
</div>
)
}
}
export default connect(
state => ({total:state.adds,people:state.persons}),
{
add:createIncrementAction,
minus:createDecrementAction,
addAsync:createIncrementAsyncAction
}
)(Add)