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
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