React-Redux:动手实现

一、实现React-Redux的过程中的DOME样式

React-Redux:动手实现_第1张图片
点击Blue变为:
React-Redux:动手实现_第2张图片


二、概述及源码

1、组件设计

React-Redux:动手实现_第3张图片

2、主要目录结构:
- public
	| - index.html
- src
	| -  index.js
	| - components
		| - react-redux.js 
		| - Contents.js
		| - Header.js
		| - ThemeSwitch.js
3、源码

注意:要先安装prop-types

(1)public文件夹下

index.html



  
    
    React App
  
  
    

(2)src文件夹下
index.js

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Header from './components/Header';
import Content from './components/Content';
import { Provider } from './components/react-redux';

//###############  redux核心函数  ############### 
function createStore (reducer) {
    let state = null;
    const listeners = [];
    const subscribe = (listener) => listeners.push(listener);
    const getState = () => state;
    const dispatch = (action) => {
        state = reducer(state, action);
        listeners.forEach((listener) => listener());
    }
    dispatch({}); // 初始化 state
    return { getState, dispatch, subscribe };
}

//############### 创建reducer、store ###############
const themeReducer = (state, action) => {
    if(!state) {
        return {
            themeColor: 'red'
        };
    } 
    switch(action.type) {
        case 'CHANGE_COLOR':
            return { ...state, themeColor: action.themeColor };
        default:
            return state;
    }
}
const store = createStore(themeReducer);

//#####################################################
class Index extends Component {
    render() {
        return (
            
) } } ReactDOM.render( , document.getElementById('root') );

react.redux.js

import React, { Component } from 'react'
import PropTypes from 'prop-types'

//connect返回一个匿名函数,这个匿名函数就是高阶组件。
export const connect = (mapStateToProps, mapDispatchToProps) => 
    (WrappedComponent) => {
        class Connect extends Component {
            static contextTypes = {
                store: PropTypes.object,
            }

            constructor() {
                super();
                this.state = { allProps: {} };
            }
          
            componentWillMount() {
                const { store } = this.context;
                this._updateProps();
                store.subscribe(() => this._updateProps());
            }
          
            _updateProps () {
                const { store } = this.context;
                let stateProps = mapStateToProps
                    ? mapStateToProps(store.getState(), this.props)// 额外传入 props,让获取数据更加灵活方便
                    : {}; // 防止 mapStateToProps 没有传入
                let dispatchProps = mapDispatchToProps
                    ? mapDispatchToProps(store.dispatch, this.props)
                    : {};
                    
                this.setState({
                    allProps: { // 整合普通的 props 和从 state 生成的 props
                        ...stateProps,
                        ...dispatchProps,
                        ...this.props
                    }
                });
            }
          
            render () {
                return 
            }
        }
        return Connect;
    }
;

//Provider是一个容器组件; 它还会把外界传给它的 props.store 放到 context
export class Provider extends Component {
    static propTypes = {
        store: PropTypes.object,
        children: PropTypes.any
    }
  
    static childContextTypes = {
        store: PropTypes.object
    }
  
    getChildContext () { //把外界传进来的 props.store 放到 context
        return {
            store: this.props.store
        }
    }
  
    render () {
        return (
            
{this.props.children}
) } }

Header.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from './react-redux';

class Header extends Component {
    static propTypes = {
        themeColor: PropTypes.string
    }; 
    render() {
        return (
            

React.js 小书

); } } //告诉connect如何获取、整合状态 const mapStateToProps = (state) => { return { themeColor: state.themeColor } }; Header = connect(mapStateToProps)(Header); export default Header;

Content.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import ThemeSwitch from './ThemeSwitch';
import { connect } from './react-redux';

class Content extends Component {
    static propTypes = {
        store: PropTypes.string,
    }

    render() {
        return (
            

React.js 小书内容

) } } //告诉connect如何获取、整合状态 const mapStateToProps = (state) => { return { themeColor: state.themeColor, } }; Content = connect(mapStateToProps)(Content); export default Content;

ThemeSwitch.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from './react-redux';

class ThemeSwitch extends Component {
    static propTypes = {
        themeColor: PropTypes.string,
        onSwitchColor: PropTypes.func
    }
    
    handleSwitchColor (color) {
        if (this.props.onSwitchColor) {
            this.props.onSwitchColor(color)
        }
    }

    render() {
        return (
            
) } } //告诉connect如何获取、整合状态 const mapStateToProps = (state) => { return { themeColor: state.themeColor } }; //告诉connect如何触发 dispatch const mapDispatchToProps = (dispatch) => { return { onSwitchColor: (color) => { dispatch({ type: 'CHANGE_COLOR', themeColor: color }); }, } }; ThemeSwitch = connect(mapStateToProps, mapDispatchToProps)(ThemeSwitch); export default ThemeSwitch;

你可能感兴趣的:(React)