借鑑redux,實現一個react狀態管理方案

react狀態管理方案有很多,其中最簡單的最常用的是redux。

redux實現

redux做狀態管理,是利用reducer和action實現的state的更新。 如果想要用redux,需要幾個步驟

  1. actions

創建actions.js

// actions.js
export const SET_NAME = 'SET_NAME';
export const setName = (name) => {
    return {
        type: SET_NAME,
        name,
    }
}

 

  1. reducer

創建reducers.js

// reducers.js
import {SET_NAME} from './actions';
const nameState = (state = '', action) => {
    switch(action.type) {
        case SET_NAME: {
            return action.name;
        }
        default: {
            return state;
        }
    }
}
export default nameState;

 

  1. 入口文

項目的入口文件

// index.js
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import rootReducer from './reducers'
import App from './App'

const store = createStore(rootReducer)

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

 

  1. App組件

業務組件代碼

import React, { Component } from 'react';
import { connect } from 'react-redux';
import {setName} from './actions';

class App extends Component {
    constructor(props) {
        super(props);
    }
    handleClick() {
        this.props.setName('張三李四')
    }
    render() {
        return (
            <div>
                {this.props.name}
                <button onClick={this.handleClick.bind(this)}>修改name</button>
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        name: state.name,
    };
};
const mapDispatchToProps = (dispatch) => {
    return {
        setName(name) {
            dispatch(setName(name));
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

 

redux實現原理

redux是狀態管理工具,react-redux使得react組件能與redux結合。

Provider

Provider是一個高階組件,他需要在最外層,才能實現store被所有子組件共享。

connect

connect方法是將react組件連接store的方法。connect方法會將組件使用到的state和需要觸發的action映射到react組件的屬性上。

詳解請看react-redux文檔

爲什麼不用redux

redux提供了非常系統完整的state管理方案,用文檔裏的一句話則是:

通過限制更新發生的時間和方式,Redux 試圖讓 state 的變化變得可預測.

因爲他很完整,所以相對複雜,需要較多的配置。在小的項目中想要更簡便的狀態管理方案,所以拋棄redux,尋找其他方案。

xudox實現

  • 確定用法
  • 完整示例
  • 原理簡介

確定用法

目的就是使用起來最簡單,因此我可能會這樣用

// 組件中使用
import React, { Component } from 'react';
import {connect} from 'xubox';

class AA extends Component {
    constructor(props) {
        super(props)
    }
    handleClick() {
        // 給組件掛在setState$方法,在這裏直接改變state值
        this.props.setState$({
            name: '張三李四'
        })
    }
    render() {
        return (
            <div>
                {this.props.name}
                <button onClick={this.handleClick.bind(this)}></button>
            </div>
        )
    }
}
// 與redux一樣,函數返回組件需要的state
const mapStateToProps = (state) => {
    return {
        name: state.name,
    };
};

// 與redux一樣用法,區別是隻傳遞mapStateToProps一個參數
connect(mapStateToProps)(AA);

 

從代碼看上去與redux好像,只不過少了dispatch緩解,改成了直接改變state。那其他設置呢?除了手動設置初始state值,其他不需要任何設置。

設置state的初始值

// 入口文件
import configureState from 'xubox';

configureState({
    name: localStorage.getItem('name') || '無名氏'
});

 

完整示例

  1. 入口文件

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './app.js'
import configure from 'xudux';
// 初始state
let state =  {
    name: '無名氏',
};

configure(state);
ReactDOM.render(
    <App />
, document.getElementById('root'));

 

  1. 組件內

app.js

import React, { Component } from 'react';
import { connect } from 'xudux';

class App extends Component {
    constructor(props) {
        super(props);
    }
    handleClick() {
        this.props.setState$({
            name: '張三李四',
        });
    }
    render() {
        return (
            <div>
                {this.props.name}
                <button onClick={this.handleClick.bind(this)}>修改name</button>
            </div>
        )
    }
}

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

export default connect(mapStateToProps)(App);

 

簡單的兩部就完成了狀態管理。示例爲一個組件內state渲染後視圖,視圖發起事件改變state,state改變引發視圖的重新渲染。多組件間的通信同理。

原理簡介

簡單介紹xudux原理。原理很簡單,connect形成高階組件,在高階組件內部監聽state的變化,如果state變化則引發傳入的react組件props發生變化,從而重新渲染。redux大概也是這樣的邏輯。

setState$方法:此方法其實是xudux內部更新state的方法,任何組件調用此方法會觸發xudux中state更新,state更新會推送給所有組件,每個組件判斷自身的state是否改變,從而決定react組件是否更新。

結尾

有興趣的大佬可以嘗試一下 github

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章