首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >现代Web开发系列教程_04

现代Web开发系列教程_04

作者头像
jeremyxu
发布于 2018-05-10 11:44:27
发布于 2018-05-10 11:44:27
1K0
举报

本篇使用redux结合react重写刚才那个很简单的hello world示例。

redux的理念

redux有三个重要的理念:单一数据源、状态是只读的、使用纯函数转换状态。具体见链接

安装redux与react-redux

1

npm install redux react-redux --save

状态转换纯函数

web-src/js/components/GreetingConstant.js

1

export const CHANGE_NAME = 'CHANGE_NAME';

web-src/js/reducers/GreetingReducer.js

代码语言:javascript
复制
import {CHANGE_NAME} from '../constants/GreetingConstant.js'

const initialState = {
  name: '',
  output: ''
}

export function GreetingReducer(state = initialState, action) {

    if (typeof state === 'undefined') {
        return initialState;
    }

    switch(action.type) {
        case CHANGE_NAME:
            return Object.assign({}, state, {
                name : action.name,
                output: 'Hello, ' + action.name
            });
        default:
            return state;
    }
};

这两个文件很简单,GreetingConstant.js里定义了action类型的常量,GreetingReducer.js就是一个普通纯函数,它的工作就是根据action转换state。

actionCreator

action是一个纯对象,其中保存了用来转换state的信息,一般包括type类型及其它参数,官方是这样定义的Actions are payloads of information that send data from your application to your store.。

actionCreator则是产生action的方法。

web-src/js/actions/GreetingAction.js

代码语言:javascript
复制
import { CHANGE_NAME } from '../constants/GreetingConstant.js'

export function changeName(name) {
    return {
        type : CHANGE_NAME,
        name: name
    };
}

组件

在redux与react项目中,组件分为Presentational Components与Container Components,有的地方叫Dump Components与Smart Components

Presentational Components

Container Components

Purpose

How things look (markup, styles)

How things work (data fetching, state updates)

Aware of Redux

No

Yes

To read data

Read data from props

Subscribe to Redux state

To change data

Invoke callbacks from props

Dispatch Redux actions

Are written

By hand

Usually generated by React Redux

简单来说Presentational Components是完全根据props属性决定行为与展现的组件,完成不感知redux的存在。Container Component则负责从state中抽取属性,分发redux's action,这里一般会用到redux的connect方法,还是看下面的代码。

web-src/js/components/GreetingComponent.js,这个就是一个Presentational Components组件

代码语言:javascript
复制
import React from 'react'

const noop = function(){};

class GreetingComponent extends React.Component{

    constructor(props){
        super(props);
        this._changeName = this.changeName.bind(this);
    }

    changeName(e){
        this.props.changeName(e.target.value);
    }

    render() {
        return (
            <div>
                <input value={this.props.name} onChange={this._changeName}/><br/>
                <label>{this.props.output}</label>
            </div>
        );
    }
};

GreetingComponent.propTypes = {
    changeName: React.PropTypes.func.isRequired,
    name: React.PropTypes.string.isRequired,
    output: React.PropTypes.string.isRequired
};

GreetingComponent.defaultProps = {
    changeName: noop,
    name: '',
    output: ''
};

export default GreetingComponent;

web-src/js/containers/GreetingContainer.js,这个就是一个Container Component组件

代码语言:javascript
复制
import { connect } from 'react-redux'

import GreetingComponent from '../components/GreetingComponent.js'

import {changeName} from '../actions/GreetingAction.js'

const mapStateToProps = (state) => {
  return {
    name: state.name,
    output: state.output
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    changeName: (name) => {
      dispatch(changeName(name))
    }
  }
}

const GreetingContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(GreetingComponent)

export default GreetingContainer

web-src/js/components/GreetingApp.js,这个就是一个Presentational Components组件

代码语言:javascript
复制
import React from 'react'

import GreetingContainer from '../containers/GreetingContainer.js'

export default class GreetingApp extends React.Component{
    render(){
        return <GreetingContainer/>
    }
}

使用Provider将state与组件关联起来

web-src/js/entries/demo3.js

代码语言:javascript
复制
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import {GreetingReducer} from '../reducers/GreetingReducer.js'
import GreetingApp from '../components/GreetingApp.js'

let store = createStore(GreetingReducer)

render(
  <Provider store={store}>
    <GreetingApp />
  </Provider>,
  document.getElementById('reactHolder')
)

这里用到了redux的Provider,它会把store附属到组件树的context上,其子组件就都可以访问到store了。

本篇源代码地址

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • redux的理念
  • 安装redux与react-redux
  • 状态转换纯函数
  • actionCreator
  • 组件
  • 使用Provider将state与组件关联起来
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档