1.我们梳理一下react和redux如何配合工作的
1.redux提供createStore方法创建创建状态数store
2.react-redux提供Provider组件把store注册到react的所有组件中
3.利用redux的combineReducers可以合并设置各个状态和对应的逻辑处理,给createStore方法使用
4.创建各个状态和逻辑,给3使用
5.创建组件,利用react-redux的connect封装组件,可以把store的状态和dispatch传给组件,在组件的this.props获取
6.组件中this.props.xx获取store的状态和dispatch,显示和调用(acton)
2.一个react+redux+react-redux的简单示例
index.html
<!doctype html> <html lang="en"> <head> <Meta charset="utf-8"> <Meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"> <Meta name="theme-color" content="#000000"> <title></title> </head> <body> <div id="root"></div> </body> </html>
src目录结构:
index.js
import React from 'react'; import ReactDOM from 'react-dom'; import registerServiceWorker from './registerServiceWorker'; //中间件 dispatch支持函数action import thunkMiddleware from 'redux-thunk' //redux 和react-redux(关联react和redux) import { createStore,applyMiddleware } from 'redux'; import { Provider } from 'react-redux'; //reducers 状态树state和逻辑操作 import indexRedux from './indexRedux.js' //app页面 import App from './App.js' //创建状态树和设置 //使用中间件 const createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore); //生成状态树对象 const store = createStore(indexRedux); //start 状态树应用到全局 通过Provider ReactDOM.render(<Provider store={store}><App /></Provider>,document.getElementById('root')); registerServiceWorker();
App.js
import React,{ Component } from 'react'; //=====引入组件===== import Sub1ReactRedux from './page/Sub1ReactRedux.js' import Sub2ReactRedux from './page/Sub2ReactRedux.js' import Sub3ReactRedux from './page/Sub3ReactRedux.js' import Sub4ReactRedux from './page/Sub4ReactRedux.js' //=====组件===== class App extends Component { render() { return ( <div> <Sub1ReactRedux/> <Sub2ReactRedux/> <Sub3ReactRedux/> <Sub4ReactRedux/> </div> ); } //生命周期函数,渲染完毕 componentDidMount() { console.log("app渲染完毕,项目开始了") } } export default App
indexRedux.js
import { combineReducers } from 'redux'; //子reducer import list from './page/Sub1Redux.js' import hello from './page/Sub2Redux.js' import ajaxinfo from './page/Sub3Redux.js' import middleware from './page/Sub4Redux.js' //合并reducer var indexRedux = combineReducers({ list,hello,ajaxinfo,middleware }) export default indexRedux
page目录结构:
Sub1.js
import React,{ Component } from 'react'; //=====组件===== class Sub1 extends Component { //添加一条数据 addone(){ var newval=document.getElementById("additem").value; this.props.ADDTODO(newval); }; render() { return ( <div> <div>{this.props.name}</div> <ul> { this.props.list.map(function(v,i){ return <li key={v.id}>{v.name}</li> }) } </ul> <input type="text" id="additem" /> <button onClick={this.addone.bind(this)}>添加一条</button> <hr /> </div> ); } componentDidMount() { console.log("sub1渲染完毕") } } export default Sub1
Sub1ReactRedux.js
import { connect } from 'react-redux'; //=====引入组件===== import Sub1 from './Sub1.js' //=====react-redux 封装组件===== // 哪些 Redux 全局的 state 是我们组件想要通过 props 获取的? function mapStateToProps(state) { return { list: state.list }; } // 哪些 action 创建函数是我们想要通过 props 获取的? function mapDispatchToProps(dispatch) { return { ADDTODO:function(newval){ dispatch({type:"ADD_TODO",name:newval}) } }; } //封装传递state和dispatch var Sub1ReactRedux = connect(mapStateToProps,mapDispatchToProps)(Sub1); export default Sub1ReactRedux
Sub1Redux.js
//reducer var listjson=[ {id:1,name:"d1111"},{id:2,name:"d222"},{id:3,name:"d333333"},{id:4,name:"d44444"} ]; function list(state = listjson,action) { switch (action.type) { case "ADD_TODO": //获取最后一个数据的id然后+1 var newid=Number(state[state.length-1].id)+1; return [ ...state,{name: action.name,id: newid} ] default: return state } } export default list
Sub2.js
import React,{ Component } from 'react'; //=====组件===== class Sub2 extends Component { render() { return ( <div> <h3>{this.props.hello}</h3> <ul> { this.props.list.map(function(v,i){ return <li key={v.id}>{v.name}</li> }) } </ul> <hr /> </div> ); } componentDidMount() { console.log("sub2渲染完毕") } } export default Sub2
Sub2ReactRedux.js
import { connect } from 'react-redux'; //=====引入组件===== import Sub2 from './Sub2.js' //=====react-redux 封装组件===== // 哪些 Redux 全局的 state 是我们组件想要通过 props 获取的? function mapStateToProps(state) { return { hello:state.hello,list: state.list }; } // 哪些 action 创建函数是我们想要通过 props 获取的? function mapDispatchToProps(dispatch) { } //封装传递state和dispatch var Sub2ReactRedux = connect(mapStateToProps)(Sub2); export default Sub2ReactRedux
Sub2Redux.js
//reducer var wh="hello"; function hello(state = wh,action) { switch (action.type) { case "A": return "hello" default: return state } } export default hello
Sub3.js
import React,{ Component } from 'react'; //=====组件===== class Sub3 extends Component { f5(){ this.props.RENAME(this.props.ajaxinfo.name+1) } res(){ this.props.RESNAME() } render() { return ( <div> 显示用户数据 <div>{this.props.ajaxinfo.name}</div> <div>{this.props.ajaxinfo.sex}</div> <div>ajax数据{this.props.ajaxinfo.more}</div> <button onClick={this.f5.bind(this)}>姓名+1</button> <button onClick={this.res.bind(this)}>姓名重置</button> <hr /> </div> ); } componentDidMount() { console.log("sub3渲染完毕") //alert(this.props.ajaxinfo.name) this.props.STARTGETMORE(); setTimeout(function(){ this.props.SUCCESSGETMORE("我是ajax数据") }.bind(this),2000) } } export default Sub3
Sub3ReactRedux.js
import { connect } from 'react-redux'; //=====引入组件===== import Sub3 from './Sub3.js' //=====react-redux 封装组件===== // 哪些 Redux 全局的 state 是我们组件想要通过 props 获取的? function mapStateToProps(state) { return { ajaxinfo: state.ajaxinfo }; } // 哪些 action 创建函数是我们想要通过 props 获取的? function mapDispatchToProps(dispatch) { return { RENAME:function(name){ dispatch({type:"RE_NAME",name:name}) },RESNAME:function(){ dispatch({type:"RES_NAME",name:"小李子"}) },STARTGETMORE:function(){ dispatch({type:"START_GET_MORE",more:"start"}) },SUCCESSGETMORE:function(more){ dispatch({type:"RES_NAME",name:more}) } }; } //封装传递state和dispatch var Sub3ReactRedux = connect(mapStateToProps,mapDispatchToProps)(Sub3); export default Sub3ReactRedux
Sub3Redux.js
//reducer var ajaxinfoinit={name:"小李子",sex:"男",isFetching: false,more:""}; function ajaxinfo(state = ajaxinfoinit,action) { switch (action.type) { case "RE_NAME": //修改姓名 return {...state,name:action.name} case "RES_NAME": //重设 return {...state,name:action.name} case "START_GET_MORE": //AJAX开始请求更多信息 return {...state,more:action.more} case "SUCCESS_GET_MORE": //请求成功返回更多信息 return {...state,more:action.more} case "ERROR_GET_MORE": //请求失败 return {...state,error:action.error} default: return state } } export default ajaxinfo
Sub4.js
import React,{ Component } from 'react'; //=====组件===== class Sub4 extends Component { getmore(){ var info=[ {val:"第n条数据"},{val:"第n+1条数据"},{val:"第n+2条数据"} ]; this.props.POSTMD(info); } removedata(){ this.props.REMOVEMD(); } render() { return ( <div> 数据处理 <div style={{display:this.props.middleware.list.length<=0?"block":"none"}}>沒有数据</div> <ul style={{display:this.props.middleware.list.length<=0?"none":"block"}}> { this.props.middleware.list.map(function(item,i){ return <li key={i}>{item.val}</li> }) } </ul> <button onClick={this.getmore.bind(this)}>加载更多(一次模拟从后台拿到3条)</button> <button onClick={this.removedata.bind(this)}>移除所有数据</button> <hr /> </div> ); } componentDidMount() { console.log("sub4渲染完毕") } } export default Sub4
Sub4ReactRedux.js
import { connect } from 'react-redux'; //=====引入组件===== import Sub4 from './Sub4.js' //=====react-redux 封装组件===== // 哪些 Redux 全局的 state 是我们组件想要通过 props 获取的? function mapStateToProps(state) { return { middleware: state.middleware }; } // 哪些 action 创建函数是我们想要通过 props 获取的? function mapDispatchToProps(dispatch) { return { POSTMD:function(info){ dispatch({type:"START_MD"}); //ajax success数据 setTimeout(function(){ dispatch({type:"SUCCESS_MD",info:info}) },2000); },REMOVEMD:function(){ dispatch({type:"REMOVE_MD",msg:""}) } }; } //封装传递state和dispatch var Sub4ReactRedux = connect(mapStateToProps,mapDispatchToProps)(Sub4); export default Sub4ReactRedux
Sub4Redux.js
//reducer var middlewareinit={ list:[ {val:"第1条数据"},{val:"第2条数据"},{val:"第3条数据"} ] }; function middleware(state = middlewareinit,action) { switch (action.type) { case "START_MD": //请求成功返回更多信息 return {list:[...state.list]} case "SUCCESS_MD": //请求成功返回更多信息 return {list:[...state.list,...action.info]} case "REMOVE_MD": //请求失败 return {list:[]} default: return state } } export default middleware