借鑑redux,實現一個react狀態管理方案
react狀態管理方案有很多,其中最簡單的最常用的是redux。
redux實現
redux做狀態管理,是利用reducer和action實現的state的更新。 如果想要用redux,需要幾個步驟
- actions
建立actions.js
// actions.js export const SET_NAME = 'SET_NAME'; export const setName = (name) => { return { type: SET_NAME, name, } }
- 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;
- 入口文
專案的入口檔案
// 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') )
- 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') || '無名氏' });
完整示例
- 入口檔案
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'));
- 元件內
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元件是否更新。
結尾
有興趣的大佬可以嘗試一下 gi