antd-design、Dva的使用

219 阅读14分钟

antd-design

1.安装

$ npm install antd --save

2.使用

组件

import React from 'react'; 
import { DatePicker } from 'antd'; 
const App = () => { 
    return <DatePicker />; 
}; 
export default App;

更换主题

高级配置

craco

可以单独创建配置文件,在你新创建的配置文件中进行配置,新建的配置文件会和隐藏的配置文件进行合并

安装
npm install @craco/craco
修改配置
/* package.json */ 
"scripts": { 
- "start": "react-scripts start", 
- "build": "react-scripts build", 
- "test": "react-scripts test", 
+ "start": "craco start", 
+ "build": "craco build", 
+ "test": "craco test", 
}
/* craco.config.js */ 
module.exports = { 
    // ... 
};

具体看官网

Dva

官网

1.概念

  • dva是一个轻量级的应用框架
  • dva是一个基于redux和redux-saga的数据流方案,内置了react、react-dom、react-router、redux、redux-saga

2.使用

image.png

安装

npm install dva

使用

  • 创建应用 let app = dva(opt)
  • 配置hooks或注册插件 app.use(hooks)
  • 注册model app.model(model)
  • 注册路由表 app.router((history, app) => {routerConfig})
  • 启动应用 app.start(selector?)

基本使用

import dva from 'dva'
// 1.创建实例对象
let app = dva()
// 2.定义组件
function App() {
  return (
    <div>App</div>
  )
}
// 3.注册路由表,需要渲染哪个组件
// 回调函数返回的值,就是需要渲染的组件
app.router(() => <App />)
// 启动
app.start('#root')

model 管理数据

model

import dva, { connect } from 'dva'
// 1.创建实例对象
let app = dva()
// 定义model
let homeModel = {
  namespace: 'home', //指定命名空间,用来区分不同的model
  // 指定当前命名空间保存的数据
  state: {
    num: 0
  },
  // 指定当前命名空间保存的reducer
  reducers: {
    add: (state, action) => {
      return { num: state.num + action.num }
    }
  }
}
let aboutModel = {
  namespace: 'about',
  state: {
    num: 1
  },
  // 指定当前命名空间保存的reducer
  reducers: {
    add: (state, action) => {
      return { num: state.num + action.num }
    }
  }
}

// 告诉dva需要使用哪个model
// app.model可多次调用
app.model(homeModel)
// app.model(aboutModel)
// 2.定义组件
function Home(props) {
  return (
    <div>
      <div>Home</div>
      <div>{props.num}</div>
      <button onClick={() => props.increment()}>+</button>
    </div>
  )
}
// 在mapStateToProps方法中告诉React-Redux, 需要将store中保存的哪些数据映射到当前组件的props上
const mapStateToProps = (state) => {
  return {
    // 从传入state的命名空间中拿到对应model保存的数据
    num: state.home.num
  }
}
// 在mapDispatchToProps方法中告诉React-Redux, 需要将哪些派发的任务映射到当前组件的props上
const mapDispatchToProps = (dispatch) => {
  return {
    increment() {
      // 获取数据的时候, 我们需要指定从哪一个命名空间的Model中获取
      // 同理在派发任务的时候, 我们也需要指定要派发给哪一个命名空间的Model
      dispatch({ type: 'home/add', num: 5 })
    }
  }
}
const AdvHome = connect(mapStateToProps, mapDispatchToProps)(Home)

function App() {
  return (
    <div>
      <>App</>
      <AdvHome />
    </div>
  )
}

// 3.注册路由表,需要渲染哪个组件
// 回调函数返回的值,就是需要渲染的组件
app.router(() => <App />)
// 启动
app.start('#root')

effects 异步处理

官网说明

类似saga

import dva, { connect } from 'dva'
// 1.创建实例对象
let app = dva()
// 定义model
let homeModel = {
  namespace: 'home', //指定命名空间,用来区分不同的model
  // 指定当前命名空间保存的数据
  state: {
    num: 0,
    info: {}
  },
  // 指定当前命名空间保存的reducer
  reducers: {
    add: (state, action) => {
      return { ...state, num: state.num + action.num }
    },
    changeInfo: (state, action) => {
      return { ...state, info: action.info }
    }
  },
  // 指定当前命名空间保存的异步操作
  effects: {
    *UserInfo(state, { put }) {
      // 获取网络数据
      const data = yield fetch('http://127.0.0.1:7001/info')
        .then((res) => {
          return res.json()
        })
        .catch(err => {
          console.log(err)
        })
      // {type: changeInfo, info: xxx}
      yield put({ type: 'changeInfo', info: data })
    }
  }
}
let aboutModel = {
  namespace: 'about',
  state: {
    num: 1
  },
  // 指定当前命名空间保存的reducer
  reducers: {
    add: (state, action) => {
      return { num: state.num + action.num }
    }
  }
}

// 告诉dva需要使用哪个model
// app.model可多次调用
app.model(homeModel)
// app.model(aboutModel)
// 2.定义组件
function Home(props) {
  return (
    <div>
      <div>Home</div>
      <div>{props.num}</div>
      <div>{props.info.name}</div>
      <div>{props.info.age}</div>
      <button onClick={() => props.increment()}>+</button>
      <button onClick={() => { props.getUserInfo() }}>获取</button>
    </div>
  )
}
// 在mapStateToProps方法中告诉React-Redux, 需要将store中保存的哪些数据映射到当前组件的props上
const mapStateToProps = (state) => {
  return {
    // 从传入state的命名空间中拿到对应model保存的数据
    num: state.home.num,
    info: state.home.info
  }
}
// 在mapDispatchToProps方法中告诉React-Redux, 需要将哪些派发的任务映射到当前组件的props上
const mapDispatchToProps = (dispatch) => {
  return {
    increment() {
      // 获取数据的时候, 我们需要指定从哪一个命名空间的Model中获取
      // 同理在派发任务的时候, 我们也需要指定要派发给哪一个命名空间的Model
      dispatch({ type: 'home/add', num: 5 })
    },
    getUserInfo() {
      dispatch({ type: 'home/UserInfo' })
    }
  }
}
const AdvHome = connect(mapStateToProps, mapDispatchToProps)(Home)

function App() {
  return (
    <div>
      <>App</>
      <AdvHome />
    </div>
  )
}

// 3.注册路由表,需要渲染哪个组件
// 回调函数返回的值,就是需要渲染的组件
app.router(() => <App />)
// 启动
app.start('#root')

subscriptions 订阅

官网说明

image.png

import dva, { connect } from 'dva'
// 1.创建实例对象
let app = dva()
// 定义model
let homeModel = {
  namespace: 'home', //指定命名空间,用来区分不同的model
  // 指定当前命名空间保存的数据
  state: {
    num: 0,
    info: {}
  },
  // 指定当前命名空间保存的reducer
  reducers: {
    add: (state, action) => {
      return { ...state, num: state.num + action.num }
    },
    changeInfo: (state, action) => {
      return { ...state, info: action.info }
    }
  },
  // 指定当前命名空间保存的异步操作
  effects: {
    *UserInfo(state, { put }) {
      // 获取网络数据
      const data = yield fetch('http://127.0.0.1:7001/info')
        .then((res) => {
          return res.json()
        })
        .catch(err => {
          console.log(err)
        })
      // {type: changeInfo, info: xxx}
      yield put({ type: 'changeInfo', info: data })
    }
  },
  // 指定当前命名空间订阅的内容
  // 调用app.start就会自动执行subscriptions
  subscriptions: {
    setup({ history, dispatch }) {
      // 监听 history 变化,当进入 `/` 时触发 `load` action
      return history.listen(({ pathname }) => {
        // if (pathname === '/') {
        //   dispatch({ type: 'load' });
        // }
        document.title = pathname
      })
    },
  },
}
let aboutModel = {
  namespace: 'about',
  state: {
    num: 1
  },
  // 指定当前命名空间保存的reducer
  reducers: {
    add: (state, action) => {
      return { num: state.num + action.num }
    }
  }
}

// 告诉dva需要使用哪个model
// app.model可多次调用
app.model(homeModel)
// app.model(aboutModel)
// 2.定义组件
function Home(props) {
  return (
    <div>
      <div>Home</div>
      <div>{props.num}</div>
      <div>{props.info.name}</div>
      <div>{props.info.age}</div>
      <button onClick={() => props.increment()}>+</button>
      <button onClick={() => { props.getUserInfo() }}>获取</button>
    </div>
  )
}
// 在mapStateToProps方法中告诉React-Redux, 需要将store中保存的哪些数据映射到当前组件的props上
const mapStateToProps = (state) => {
  return {
    // 从传入state的命名空间中拿到对应model保存的数据
    num: state.home.num,
    info: state.home.info
  }
}
// 在mapDispatchToProps方法中告诉React-Redux, 需要将哪些派发的任务映射到当前组件的props上
const mapDispatchToProps = (dispatch) => {
  return {
    increment() {
      // 获取数据的时候, 我们需要指定从哪一个命名空间的Model中获取
      // 同理在派发任务的时候, 我们也需要指定要派发给哪一个命名空间的Model
      dispatch({ type: 'home/add', num: 5 })
    },
    getUserInfo() {
      dispatch({ type: 'home/UserInfo' })
    }
  }
}
const AdvHome = connect(mapStateToProps, mapDispatchToProps)(Home)

function App() {
  return (
    <div>
      <>App</>
      <AdvHome />
    </div>
  )
}

// 3.注册路由表,需要渲染哪个组件
// 回调函数返回的值,就是需要渲染的组件
app.router(() => <App />)
// 启动
app.start('#root')

Dva路由

import dva, { connect } from 'dva'
import { Router, Route } from 'dva/router'
// import createHistory from 'history/createBrowserHistory';
const createHistory = require('history').createBrowserHistory
// 改成
// import { createBrowserHistory as createHistory } from 'history'
// 1.创建实例对象
/**
 * 注意点:在通过dva创建dva实例的时候,这个方法是可以接收一个对象
 *        可以在这个对象中指定dva路由的模式
 *        如果在创建dva实例的时候,没有指定路由的模式,那么默认的是hash模式
 */

const app = dva({
  history: createHistory(),
})
// 定义model
let homeModel = {
  namespace: 'home', //指定命名空间,用来区分不同的model
  // 指定当前命名空间保存的数据
  state: {
    num: 0,
    info: {}
  },
  // 指定当前命名空间保存的reducer
  reducers: {
    add: (state, action) => {
      return { ...state, num: state.num + action.num }
    },
    changeInfo: (state, action) => {
      return { ...state, info: action.info }
    }
  },
  // 指定当前命名空间保存的异步操作
  effects: {
    *UserInfo(state, { put }) {
      // 获取网络数据
      const data = yield fetch('http://127.0.0.1:7001/info')
        .then((res) => {
          return res.json()
        })
        .catch(err => {
          console.log(err)
        })
      // {type: changeInfo, info: xxx}
      yield put({ type: 'changeInfo', info: data })
    }
  },
  // 指定当前命名空间订阅的内容
  // 调用app.start就会自动执行subscriptions
  subscriptions: {
    setup({ history, dispatch }) {
      // 监听 history 变化,当进入 `/` 时触发 `load` action
      return history.listen(({ pathname }) => {
        // if (pathname === '/') {
        //   dispatch({ type: 'load' });
        // }
        document.title = pathname
      })
    },
  },
}
let aboutModel = {
  namespace: 'about',
  state: {
    count: 1
  },
  // 指定当前命名空间保存的reducer
  reducers: {
    add: (state, action) => {
      return { count: state.count + action.count }
    }
  }
}

// 告诉dva需要使用哪个model
// app.model可多次调用
app.model(homeModel)
app.model(aboutModel)
// 2.定义组件
function Home(props) {
  return (
    <div>
      <div>Home</div>
      <div>{props.num}</div>
      <div>{props.info.name}</div>
      <div>{props.info.age}</div>
      <button onClick={() => props.increment()}>+</button>
      <button onClick={() => { props.getUserInfo() }}>获取</button>
    </div>
  )
}
// 在mapStateToProps方法中告诉React-Redux, 需要将store中保存的哪些数据映射到当前组件的props上
const mapStateToProps = (state) => {
  return {
    // 从传入state的命名空间中拿到对应model保存的数据
    num: state.home.num,
    info: state.home.info
  }
}
// 在mapDispatchToProps方法中告诉React-Redux, 需要将哪些派发的任务映射到当前组件的props上
const mapDispatchToProps = (dispatch) => {
  return {
    increment() {
      // 获取数据的时候, 我们需要指定从哪一个命名空间的Model中获取
      // 同理在派发任务的时候, 我们也需要指定要派发给哪一个命名空间的Model
      dispatch({ type: 'home/add', num: 5 })
    },
    getUserInfo() {
      dispatch({ type: 'home/UserInfo' })
    }
  }
}
const AdvHome = connect(mapStateToProps, mapDispatchToProps)(Home)
function About(props) {
  return (
    <div>
      <div>About</div>
      <div>{props.count}</div>
      <button onClick={() => props.increment()}>about+</button>
    </div>
  )
}
// 在mapStateToProps方法中告诉React-Redux, 需要将store中保存的哪些数据映射到当前组件的props上
const mapStateToProps2 = (state) => {
  return {
    // 从传入state的命名空间中拿到对应model保存的数据
    count: state.about.count
  }
}
// 在mapDispatchToProps方法中告诉React-Redux, 需要将哪些派发的任务映射到当前组件的props上
const mapDispatchToProps2 = (dispatch) => {
  return {
    increment() {
      // 获取数据的时候, 我们需要指定从哪一个命名空间的Model中获取
      // 同理在派发任务的时候, 我们也需要指定要派发给哪一个命名空间的Model
      dispatch({ type: 'about/add', count: 5 })
    }
  }
}
const AdvAbout = connect(mapStateToProps2, mapDispatchToProps2)(About)
function App(props) {
  return (
    <div>
      {/* <>App</>
      <AdvHome />
      <hr />
      <AdvAbout /> */}
      <Router history={props.history}>
        {/* 一个根 */}
        <>
          <Route path={'/home'} component={AdvHome}></Route>
          <Route path={'/about'} component={AdvAbout}></Route>
        </>
      </Router>
    </div>
  )
}

// 3.注册路由表,需要渲染哪个组件
// 回调函数返回的值,就是需要渲染的组件
// app.router(() => <App />)
// dva的router方法在执行回调函数的时候会传递一个对象给我们,可以从这个对象中结构出当前路由模式
// 如果在创建dva实例的时候没有指定模式,那么得到的就是hash模式
// 如果在创建dva实例的时候制定了模式,那么得到的就是指定的模式
app.router(({ history }) => <App history={history} />)
// 启动
app.start('#root')

路由跳转

官网

import { Router, Route, Link } from 'dva/router'

方法一

<Router history={props.history}>
{/* 一个根 */}
<>
  <Link to={'/home'}>Home</Link>
  <Link to={'/about'}>About</Link>
  <Route path={'/home'} component={AdvHome}></Route>
  <Route path={'/about'} component={AdvAbout}></Route>
</>
</Router>

方法2

goToAbout: () => {
  dispatch(routerRedux.push('/about'))
  //  dispatch(routerRedux.goBack());
}

具体实现

import dva, { connect } from 'dva'
import { Router, Route, Link, routerRedux } from 'dva/router'
// import createHistory from 'history/createBrowserHistory';
const createHistory = require('history').createBrowserHistory
// 改成
// import { createBrowserHistory as createHistory } from 'history'
// 1.创建实例对象
/**
 * 注意点:在通过dva创建dva实例的时候,这个方法是可以接收一个对象
 *        可以在这个对象中指定dva路由的模式
 *        如果在创建dva实例的时候,没有指定路由的模式,那么默认的是hash模式
 */

const app = dva({
  history: createHistory(),
})
// 定义model
let homeModel = {
  namespace: 'home', //指定命名空间,用来区分不同的model
  // 指定当前命名空间保存的数据
  state: {
    num: 0,
    info: {}
  },
  // 指定当前命名空间保存的reducer
  reducers: {
    add: (state, action) => {
      return { ...state, num: state.num + action.num }
    },
    changeInfo: (state, action) => {
      return { ...state, info: action.info }
    },

  },
  // 指定当前命名空间保存的异步操作
  effects: {
    *UserInfo(state, { put }) {
      // 获取网络数据
      const data = yield fetch('http://127.0.0.1:7001/info')
        .then((res) => {
          return res.json()
        })
        .catch(err => {
          console.log(err)
        })
      // {type: changeInfo, info: xxx}
      yield put({ type: 'changeInfo', info: data })
    }
  },
  // 指定当前命名空间订阅的内容
  // 调用app.start就会自动执行subscriptions
  subscriptions: {
    setup({ history, dispatch }) {
      // 监听 history 变化,当进入 `/` 时触发 `load` action
      return history.listen(({ pathname }) => {
        // if (pathname === '/') {
        //   dispatch({ type: 'load' });
        // }
        document.title = pathname
      })
    },
  },
}
let aboutModel = {
  namespace: 'about',
  state: {
    count: 1
  },
  // 指定当前命名空间保存的reducer
  reducers: {
    add: (state, action) => {
      return { count: state.count + action.count }
    }
  }
}

// 告诉dva需要使用哪个model
// app.model可多次调用
app.model(homeModel)
app.model(aboutModel)
// 2.定义组件
function Home(props) {
  return (
    <div>
      <div>Home</div>
      <div>{props.num}</div>
      <div>{props.info.name}</div>
      <div>{props.info.age}</div>
      <button onClick={() => props.increment()}>+</button>
      <button onClick={() => { props.getUserInfo() }}>获取</button>
      <button onClick={() => { props.goToAbout() }}>to - about</button>
    </div>
  )
}
// 在mapStateToProps方法中告诉React-Redux, 需要将store中保存的哪些数据映射到当前组件的props上
const mapStateToProps = (state) => {
  return {
    // 从传入state的命名空间中拿到对应model保存的数据
    num: state.home.num,
    info: state.home.info
  }
}
// 在mapDispatchToProps方法中告诉React-Redux, 需要将哪些派发的任务映射到当前组件的props上
const mapDispatchToProps = (dispatch) => {
  return {
    increment() {
      // 获取数据的时候, 我们需要指定从哪一个命名空间的Model中获取
      // 同理在派发任务的时候, 我们也需要指定要派发给哪一个命名空间的Model
      dispatch({ type: 'home/add', num: 5 })
    },
    getUserInfo() {
      dispatch({ type: 'home/UserInfo' })
    },
    goToAbout: () => {
      dispatch(routerRedux.push('/about'))
      //  dispatch(routerRedux.goBack());
    }
  }
}
const AdvHome = connect(mapStateToProps, mapDispatchToProps)(Home)
function About(props) {
  return (
    <div>
      <div>About</div>
      <div>{props.count}</div>
      <button onClick={() => props.increment()}>about+</button>
    </div>
  )
}
// 在mapStateToProps方法中告诉React-Redux, 需要将store中保存的哪些数据映射到当前组件的props上
const mapStateToProps2 = (state) => {
  return {
    // 从传入state的命名空间中拿到对应model保存的数据
    count: state.about.count
  }
}
// 在mapDispatchToProps方法中告诉React-Redux, 需要将哪些派发的任务映射到当前组件的props上
const mapDispatchToProps2 = (dispatch) => {
  return {
    increment() {
      // 获取数据的时候, 我们需要指定从哪一个命名空间的Model中获取
      // 同理在派发任务的时候, 我们也需要指定要派发给哪一个命名空间的Model
      dispatch({ type: 'about/add', count: 5 })
    }
  }
}
const AdvAbout = connect(mapStateToProps2, mapDispatchToProps2)(About)
function App(props) {
  return (
    <div>
      {/* <>App</>
      <AdvHome />
      <hr />
      <AdvAbout /> */}
      <Router history={props.history}>
        {/* 一个根 */}
        <>
          <Link to={'/home'}>Home</Link>
          <Link to={'/about'}>About</Link>
          <Route path={'/home'} component={AdvHome}></Route>
          <Route path={'/about'} component={AdvAbout}></Route>
        </>
      </Router>
    </div>
  )
}

// 3.注册路由表,需要渲染哪个组件
// 回调函数返回的值,就是需要渲染的组件
// app.router(() => <App />)
// dva的router方法在执行回调函数的时候会传递一个对象给我们,可以从这个对象中结构出当前路由模式
// 如果在创建dva实例的时候没有指定模式,那么得到的就是hash模式
// 如果在创建dva实例的时候制定了模式,那么得到的就是指定的模式
app.router(({ history }) => <App history={history} />)
// 启动
app.start('#root')

app = dva(opts)---opts

  • initialState: 如果同时在initialState和Model中都指定了数据的初始值, 那么initialState的优先级高于Model
  • onError: effect 执行错误或 subscription 通过 done 主动抛错时触发,可用于管理全局出错状态
  • onAction: 在 action 被 dispatch 时触发,用于注册 redux 中间件
  • onStateChange: state 改变时触发,可用于同步 state 到 localStorage,服务器端等
  • onReducer: 封装 reducer 执行,全局拦截reducer
  • onEffect: 封装 effect 执行,全局拦截effect
  • onHmr: 全局处理热替换
  • extraReducers: 指定额外的 reducer
  • extraEnhancers: 指定额外的 StoreEnhancer
import dva, {connect} from 'dva';
import {Router, Route, Link, routerRedux } from 'dva/router';
import createHistory from 'history/createBrowserHistory';
import createLogger from 'redux-logger';
/*
onError:          effect 执行错误或 subscription 通过 done 主动抛错时触发,可用于管理全局出错状态
onAction:        在 action 被 dispatch 时触发,用于注册 redux 中间件
onStateChange:     state 改变时触发,可用于同步 state 到 localStorage,服务器端等
onReducer:          封装 reducer 执行,全局拦截reducer
onEffect:           封装 effect 执行,全局拦截effect
onHmr:              全局处理热替换
extraReducers:      指定额外的 reducer
extraEnhancers:     指定额外的 StoreEnhancer
* */
// 1.创建实例对象
let app = dva({
    history: createHistory(),
    // 注意点: 如果同时在initialState和Model中都指定了数据的初始值, 那么initialState的优先级高于Model
    initialState:{
        home:{
            num: 777,
            info: {
                name: 'it666',
                age: 666
            }
        }
    },
    onError: (error)=>{
        // 如果在effects中发生了错误, 并且在effects中没有捕获错误, 那么就会在onError中捕获
        // 如果在subscriptions中通过done传递了错误, 那么也会在onError中捕获
        alert(error.message);
    },
    // 在dva中dva的onAction就是过去我们使用的applyMiddleware()
    // onAction作用: 用来注册中间件
    onAction: createLogger
});
// 定义一个Model
let homeModel = {
    // 指定当前Model的命名空间名称
    namespace: 'home',
    // 指定当前命名空间保存的数据
    state: {
        num: 666,
        info:{}
    },
    // 指定当前命名空间保存的reducers
    reducers: {
        // reducers中key作用, 类型
        // {type: add, playload: xxx}
        add: (state, action)=>{
            return {...state ,num: state.num + action.num};
        },
        // {type: sub, playload: xxx}
        sub: (state, action)=>{
            return {...state, num: state.num + action.num};
        },
        // {type: changeInfo, info: xxx}
        changeInfo: (state, action)=>{
            return {...state, info: action.info};
        }
    },
    // 指定当前命名空间保存的异步操作
    effects:{
        // {type: asyncUserInfo}
        *asyncUserInfo(state, {put}) {
            // 获取网络数据
            const data = yield fetch('http://127.0.0.1:7001/info')
                .then((response)=>{
                    return response.json();
                })
                // .catch((error)=>{
                //     console.log('effects中捕获',error);
                // });
            yield put({type:'changeInfo', info: data});
        }
    },
    // 指定当前命名空间订阅的内容
    subscriptions: {
        setup({ history, dispatch }, done) {
            console.log('setup被执行了');
            // 监听 history 变化,当进入 `/` 时触发 `load` action
            return history.listen(({ pathname }) => {
                document.title = pathname;
            });
        },
        change({ history, dispatch }, done){
            console.log('change被执行了');
            // done(new Error('自定义错误'));
        }
    }
}
let aboutModel = {
    // 指定当前Model的命名空间名称
    namespace: 'about',
    // 指定当前命名空间保存的数据
    state: {
        count: 123
    },
    // 指定当前命名空间保存的reducers
    reducers: {
        // reducers中key作用, 类型
        // {type: add, playload: xxx}
        add: (state, action)=>{
            return {count: state.count + action.count};
        },
        // {type: sub, playload: xxx}
        sub: (state, action)=>{
            return {count: state.count - action.count};
        },
    }
}
// 告诉dva需要使用哪个model
app.model(homeModel);
app.model(aboutModel);

// 2.定义组件
function Home(props){
    return (
        <div>
            <p>{props.num}</p>
            <button onClick={()=>{props.increment()}}>增加</button>
            <button onClick={()=>{props.decrement()}}>减少</button>
            <hr/>
            <p>{props.info.name}</p>
            <p>{props.info.age}</p>
            <button onClick={()=>{props.getUserInfo()}}>获取</button>
            <hr/>
            <button onClick={()=>{props.go2About()}}>跳转到About</button>
        </div>
    )
}
// 在mapStateToProps方法中告诉React-Redux, 需要将store中保存的哪些数据映射到当前组件的props上
const mapStateToProps1 = (state)=>{
    return {
        // 需要从传入state的命名空间中拿到对应Model保存的数据
        num: state.home.num,
        info: state.home.info
    }
};
// 在mapDispatchToProps方法中告诉React-Redux, 需要将哪些派发的任务映射到当前组件的props上
const mapDispatchToProps1 = (dispatch) =>{
    return {
        increment(){
            // 获取数据的时候, 我们需要指定从哪一个命名空间的Model中获取
            // 同理在派发任务的时候, 我们也需要指定要派发给哪一个命名空间的Model
            dispatch({type:'home/add', num:1});
        },
        decrement(){
            dispatch({type:'home/sub', num:1});
        },
        getUserInfo(){
            dispatch({type:'home/asyncUserInfo'});
        },
        go2About(){
            dispatch(routerRedux.push('/about'));
        }
    }
};
const AdvHome = connect(mapStateToProps1, mapDispatchToProps1)(Home);

function About(props){
    return (
        <div>
            <p>{props.count}</p>
            <button onClick={()=>{props.increment()}}>增加</button>
            <button onClick={()=>{props.decrement()}}>减少</button>
            <hr/>
            <button onClick={()=>{props.go2Home()}}>返回上一页</button>
        </div>
    )
}
// 在mapStateToProps方法中告诉React-Redux, 需要将store中保存的哪些数据映射到当前组件的props上
const mapStateToProps2 = (state)=>{
    return {
        // 需要从传入state的命名空间中拿到对应Model保存的数据
        count: state.about.count
    }
};
// 在mapDispatchToProps方法中告诉React-Redux, 需要将哪些派发的任务映射到当前组件的props上
const mapDispatchToProps2 = (dispatch) =>{
    return {
        increment(){
            // 获取数据的时候, 我们需要指定从哪一个命名空间的Model中获取
            // 同理在派发任务的时候, 我们也需要指定要派发给哪一个命名空间的Model
            dispatch({type:'about/add', count:2});
        },
        decrement(){
            dispatch({type:'about/sub', count:2});
        },
        go2Home(){
            dispatch(routerRedux.goBack());
        }
    }
};
const AdvAbout = connect(mapStateToProps2, mapDispatchToProps2)(About);

function App(props){
    return (
        <Router history={props.history}>
            <>
                <Link to={'/home'}>Home</Link>
                <Link to={'/about'}>About</Link>

                <Route path={'/home'} component={AdvHome}></Route>
                <Route path={'/about'} component={AdvAbout}></Route>
            </>
        </Router>
    )
}

// 3.注册路由表, 告诉dva需要渲染哪个组件
app.router(({ history })=> <App history={history}/>);

// 4.启动dva
app.start('#root');


学习笔记