zoukankan      html  css  js  c++  java
  • redux使用教程详细介绍

    本文介绍redux的使用

    1. 安装

      cnpm install redux --save
      cnpm install react-redux --save
      cnpm install redux-devtools --save-dev
      如果你之前使用过vuex,我相信redux对于你来说就是易如反掌
      redux官网将的很杂很乱,但是实用的东西就那么点
      
    2. action

      action就是一个对象,用来描述你要修改store状态树中的数据
      {
          type: 'change_name',
          name: 'yejiawei'
      }
      type字段必须要有,这是约定
      
    3. action创建函数

      正常情况下,你需要给每一个action定义一个函数,从而方便调用
      export function changeName (value) {
          return {
              type: 'change_name',
              name: value
          }
      }
      
    4. Reducer

      Reducer的作用,就是将不同的action汇总,然后返回相应的state
      const initialState = {
          name: 'haha'
      }
      function firstDemo (state = initialState, action) {
          switch (action.type) {
              case "change_name":
                  return Object.assign({},state,{
                      name: action.name
                  })
              default: 
                  return state
          }
      }
      返回值必须是全新的
      
    5. 拆分reducer

      实际开发中都是模块化的,有必要将不同模块的reducer分开
      import { combineReducers } from 'redux'
      combineReducers({firstDemo,firstDemo1})
      
    6. store

      创建store是非常简单的
      import { createStore } from 'redux'
      将上面创建的reducer当做参数传递即可
      let store = createStore(firstDemo)
      store.getState() // 获取store中的数据
      let unsubscribe = store.subscribe( () => {
          ...
      } ) // 监听器
      store.dispatch(changeName('yejiawei')) // 调用action修改store中的state
      unsubscribe() // 注销监听器
      
    7. 在react组件中使用redux

      下面我将列出,正常项目开发的结构
      index.js
          import React from 'react'
          import ReactDOM from 'react-dom'
          import { Provider } from 'react-redux'
          import store from './store.js'
          import App from './app.js'
          ReactDOM.render(
              <Provider store={store}> 
                  <App />
              </Provider>,
              document.getElementById('root')
          )
          使用 Provider 组件传递store到react组件中
      app.js
          import React from 'react'
          import MyComponent1 from './component1.js'
          import { connect } from 'react-redux'
          class MyComponent extends React.Component {
              render () {
                  return (
                      <div>
                          <MyComponent1 {...this.props}></MyComponent1>
                      </div>
                  )
              }
          }
          function appWant(state) {
              return state
          }
          export default connect(appWant)(MyComponent)
          使用connect方法将react组件连接到redux中,接受一个回调函数,并且回调函数的参数就是store中的state
          ** 原则,使用connect方法尽量只在容器组件中使用,其余的子组件如果也想访问store,就通过props传递即可
      store.js
          import { createStore } from 'redux'
          const initialState = {
              message: 'yejiawei'
          }
          function firstApp (state = initialState, action) {
              switch (action.type) {
                  case "change_message":
                      return Object.assign({},state,{
                      message: action.message
                      })
                  default: 
                      return state
              }
          }
          let store = createStore(firstApp);
          export default store
          此文件专门用来管理和生成store的,同时还可以将reducer专门再生成一个reducer.js管理
      component1.js
          此组件代表类似的子组件
          import React from 'react'
          import { delayData } from './actions.js'
          class MyComponent extends React.Component {
              componentDidMount() {
                  this.props.dispatch(changeMessage('我改变了'))
              }
              render() {
                  return (
                      <div style={{"height": "200px","width": "200px","background": "red","position": "absolute","top": "100px", "left": 0}}>我是组件一{this.props.message}</div>
                  )
              }
          }
          export default MyComponent
          在子组件中访问store中的state和dispatch通过props直接访问即可
      actions.js
          此文件专门用来处理redux中的action生成函数
          export function changeMessage (text) {
              return {
                  type: 'change_message',
                  message: text
              }
          }
      
    8. 在react组件中使用redux补充

      上面讲到的connect方法,还可以传递其他参数
      注意到我们传递给connect方法的参数是如下的这个函数
          function appWant(state) {
              return state
          }
          这个函数会在state改变的时候更新整个app组件,也就是说不管你在哪里dispatch了,那么整个app都会重新更新,性能损失
          所以可以选择只传递一部分state,如下
          function appWant(state,ownProps) {
              return {
                  age: state.age
              }
          }
          然后在其他的组件中也调用connect方法,管理自己的state,而不是只通过props传递,这样可以提高性能
      另外也可以把action单独传递或者传递一部分,我不建议这样做,对性能没有任何提高,反而提升代码复杂度,直接使用dispatch简单清晰明了
          在app.js文件中改成如下代码
              import React from 'react'
              import MyComponent1 from './component1.js'
              import { connect } from 'react-redux'
              import { bindActionCreators } from 'redux';
              import { delayData } from './actions.js'
              class MyComponent extends React.Component {
                  render () {
                      return (
                          <div>
                              <MyComponent1 {...this.props}></MyComponent1>
                          </div>
                      )
                  }
              }
              function appWant(state) {
                  return {
                      age: state.age
                  }
              }
              function funcWant(dispatch) {
                  return {
                      demo: bindActionCreators({delayData},dispatch)
                  }
              }
              export default connect(appWant,funcWant)(MyComponent)
          然后再component1.js中,就不需要通过dispatch调用了
              this.props.demo.delayData('我又变了');
      
    9. 异步action

      上面讲的内容是同步的,也就是说dispatch方法调用后,store中的state立即发生改变
      那么,现在有一个需求是,dispatch的写法不发生任何改变,还可以进行异步操作
      如何操作?只需要将action返回一个函数,然后在函数里面进行异步处理就完事儿了
      要实现这个操作就要借助 redux-thunk-middleware 中间件
      安装 cnpm install --save redux-thunk
      然后将上面的store.js文件改成下面的
          import { createStore, applyMiddleware  } from 'redux' // 导入applyMiddleware方法用来使用中间件
          import thunkMiddleware from 'redux-thunk' // 导入中间件
          const initialState = {
              message: 'yejiawei'
          }
          function firstApp (state = initialState, action) {
              switch (action.type) {
              case "change_message":
                  return Object.assign({},state,{
                      message: action.message
                  })
              default: 
                  return state
              }
          }
          let store = createStore(firstApp,applyMiddleware(thunkMiddleware)); // 将中间件应用于store中
          export default store
      然后再actions.js中添加一个异步action
          export function delayData (value) {
              return (dispatch) => {
                  setTimeout( () => {
                      dispatch(changeMessage(value))
                  },1000 )
              }
          }
      最后,直接在component1.js文件中直接调用即可
          import React from 'react'
          import { delayData } from './actions.js'
          class MyComponent extends React.Component {
              componentDidMount() {
                  this.props.dispatch(delayData('我改变了'))
              }
              render() {
                  return (
                      <div style={{"height": "200px","width": "200px","background": "red","position": "absolute","top": "100px", "left": 0}}>我是组件一{this.props.message}</div>
                  )
              }
          }
          export default MyComponent
      
    10. 异步action的补充一

      上面在定义异步action时,在返回的函数里面传递了dispatch参数,其实它还支持如下的参数
      还是借助上面的例子
      传递getState获取store中的state
          export function delayData (value) {
              return (dispatch,getState) => {
                  setTimeout( () => {
                      dispatch(changeMessage(value))
                      console.log(getState())
                  },1000 )
              }
          }
      传递自定义参数
          在store中将创建store的代码改成
              let store = createStore(firstApp,applyMiddleware(thunkMiddleware.withExtraArgument( {a: 'aaa', b: 'bbb'} )));
          然后再actions.js中获取参数
              export function delayData (value) {
                  return (dispatch, getState, {a,b}) => {
                      setTimeout( () => {
                          dispatch(changeMessage(value))
                          console.log(a,b)
                          console.log(getState())
                      },1000 )
                  }
              }
      
  • 相关阅读:
    pychram 2018-01 安装pyQT5报错
    pyqt 8行内就可以跑一个浏览器
    sql server无log ldf日志文件附件mdf数据库重新生成ldf日志文件
    解决Specifying a namespace in include()withou providing an app_name
    Java 连接池的工作原理(转)
    使用from __future__ import unicode_literals时要注意的问题
    详细介绍Redis的几种数据结构以及使用注意事项(转)
    再谈Redis应用场景(转)
    Redis的LRU机制(转)
    深入理解Redis主键失效原理及实现机制(转)
  • 原文地址:https://www.cnblogs.com/ye-hcj/p/7751261.html
Copyright © 2011-2022 走看看