• react+redux基础用法


    在学react的是,发现一旦我们封装好了我们的组件,那么我们的项目就跟搭积木一样简单快速,可是我们发现了一个问题,在一个页面往往会嵌套很多的组件,子组件必须要通过父组件传递参数才能渲染出数据,我们回想一下我们之前构建过的所有react应用,数据都是由最顶层父组件(页面组件)一层层向下传递的。

    这也是深层次的组件之间通讯困难的原因:数据的传递是单向的,子组件的数据只能就近获取,但是真正的数据源却离得太远,没有捷径可以直接通知数据源更新状态。

    redux的出现改变了react的这种窘迫处境,它提供了整个应用的唯一数据源store,这个数据源是随处可以访问的,不需要靠父子相传,并且还提供了(间接)更新这个数据源的方法,并且是随处可使用的!

    那么redux是如何工作的呢?这里我借用阮一峰react讲解redux的图来说明:
    用户看到的是能是我们的页面,那么用户如何跟我们的数据互动呢。首先初始化页面,我们会渲染store里面的初始数据,
    store 是redux提供的唯一数据源,它存储了整个应用的state,并且提供了获取state的方法,即store.getState()
    现在用户点击了某个按钮,那么这个时候用户就触发了一个动作,称之为action,action只是记录了你刚才"做了什么动作",但是就是知道你干了这个事情,至于事情会发生什么作用,这个并不是你说的算的,就要引入我们的reducer了,如果说action就是你平常做的事,那么reducer就是国家的法律,根据你的事法律会给你相应的后果。
     
    1.我们先看action
    action是一个对象,记录本次事件的类型,以便对应相应的结果,除了type属性的其他属性我们称之为载荷(payload),除了type属性外,其他属性都是非必选的。
    {
      type: 'CHANGE_LIST',
      data: [1,2,3,4]//这个是假数据,这里当做需要变成的数据,一般是后台拿到的
    }

    接下来我们要触发这个事件

    2.在redux中触发这个事件的方式就是:

    dispatch({
      type: 'CHANGE_LIST',
      data:[1,2,3,4] 
    })

    3.到这里我们触发了事件,那么事件会产生啥效果呢,这里就提到我们的reducer

    假设我们现在有一个列表组件,那么它的数据格式应该可以如下:

    // store.getState()
    
    {
      list: {
            products:['name','age','haha','gege']
      }
     
    }

    现在我们做了步骤2的action操作,那么reducer应该是这样的:

    function reducer(state, action) {
      switch (action.type) {
        case 'CHANGE_LIST':
        return {
          list: {
            products:action.data//修改给定的数据
          } 
        }
        default:
        return state  // 没有匹配的action type,返回原来的state
      }
    }
     
     到此为止我们知道这个操作会产生的效果就是原来的数组products从   ['name','age','haha','gege']  变成了  [1,2,3,4]。
    4.拆分reducer
    我们在react真实的项目肯定包含许多的组件,不能把所有组件的reducer写在一个函数里面,这样会显得更复杂以及文件特别大,所以我们把上面的reducer改写一下
    function listReducer(state, action) {
      switch (action.type) {
        case 'CHANGE_LIST':
        return {
            products:action.data//修改给定的数据
        }
        default:
        return state  // 没有匹配的action type,返回原来的state
      }
    }
    
    function reducer(state, action) {
      return {
        list: listReducer(state.list, action),
      }
    }

    可以看出达到的效果是一致的,刚好redux为reducer的合并提供了一个简单的方法combineReducers,

    function list(state, action) {
      switch (action.type) {
        case 'CHANGE_LIST':
        return {
          products:action.data
        }
    
        default:
        return state  // 没有匹配的action type,返回原来的state
      }
    }
    
    function dialog(state, action) {
      switch (action.type) {
        case 'SHOW_DIALOG':
        return {
          status: true
        }
    
        case 'CLOSE_DIALOG':
        return {
          status: false
        }
    
        default:
        return state  // 没有匹配的action type,返回原来的state
      }
    }
    
    export default combineReducers({
      list,
      dialog
    })

    5.生成store,在我们项目的入口文件app.js中:

    import React, { Component, PropTypes } from 'react'
    import ReactDom from 'react-dom'
    
    // 引入redux
    import { createStore, applyMiddleware } from 'redux'
    import { Provider, connect } from 'react-redux'
    
    // 引入reducer
    import * as reducers from './redux/reducer.js'
    import { combineReducers } from 'redux'
    
    //引入组件
    import Index from './component/index.js'
    
    //把多个组件的reducer合成总的reducer
    const reducer = combineReducers(reducers)
    
    // 创建store,这个是整个应用唯一的
    const store = createStore(reducer)
    
    ReactDom.render(
        <Provider store={store}>
            <Index />
        </Provider>,
        document.getElementById('root')
    )

    然后看看我们的Index组件是个啥样子:

    import React, { Component } from 'react'
    import { connect } from 'react-redux'
    
    import List from './list.js'
    
    class Index extends Component {
        constructor(props) {
            super(props);
        }
        render () {
            return (
                <div>
                    <List />
                </div>
            )
        }
    }
    
    function mapStateToProps(state) {
        return state  //对应本组件需要的传入的props
    }
    
    export default connect(mapStateToProps)(Index)//关联到store上

    下面最重要的看看List组件:

    import React, { Component } from 'react'
    import PropTypes from 'prop-types'
    import { connect } from 'react-redux'
    
    class List extends Component {
        constructor(props) {
            super(props);
        }
        render() {
            var html = this.props.products.map(function(val,i) {
                return <li key={i}>{val}</li>
            })
    
            return (
                <div>
                    <ul>
                        {html}
                    </ul>
                    <button onClick={this.props.change}>改变数组</button>
                </div>
            )
        }
    }
    
    function mapStateToProps(state) {
        var info = state.list
    
        return {
            products:info.products//对应本组件props需要的属性products
        }
    }
    
    function mapDispatchToProps(dispatch) {
      return {
        change () {//这里change方法对应的是这个组件需要外部传入的change方法
                    dispatch({
                        type: 'CHANGE_LIST',
                        data:[1,2,3,4]
                    })
                }
            })
          
        }
      }
    }
    
    export default connect(mapStateToProps,mapDispatchToProps)(List)

     这里只是简单介绍了redux基本知识,但是在实际的项目中如何应用呢,实际的项目react和redux结合如何搭建框架呢,这个下篇文章将会列出一个真实的项目。

  • 相关阅读:
    我的第二个思维导图,用来介绍框架
    如何减少基于DataSet框架的代码输入量(一)
    近日
    关于客户端如何获取服务器时间的方法
    匹配用逗号分隔的数字(防sql注入检查)
    十六进制字符串转整形
    sql获取自增行号
    body不出现滚动条方法
    vs2010 无法调试 无法进入断点 断点无效
    Textarea 高度自适应 根据内容自适应高度
  • 原文地址:https://www.cnblogs.com/zhenfei-jiang/p/7280167.html
Copyright © 2020-2023  润新知