github
爲何須要狀態管理?
爲何是mobx
,而不是redux
或者直接context
mobx
跟vuex
一個道理,我試試這個不用介紹了吧,本身googlevue
這個我也無論, ssr、同構嘛,也就那回事。react
npm i --save-dev babel-plugin-transform-decorators-legacy
.babelrcgit
{ "presets": ["es2015", "stage-1"], "plugins": ["transform-decorators-legacy"] }
// .babelrc { "presets": [ "react", "es2015", "stage-1" ], "plugins":[ "transform-decorators", ["transform-class-properties", { "loose": true}] ] } // package.json { "babel-core": "7.0.0-beta.3", "babel-preset-es2015": "7.0.0-beta.3", "babel-preset-react": "7.0.0-beta.3", "babel-preset-stage-1": "7.0.0-beta.3", "babel-plugin-transform-decorators": "^6.24.1" }
import A from './mobx/A' import B from './mobx/B' const aStore = new A(); const bStore = new B(); const stores = { aStore, bStore, } class App extends Component { render() { return ( <Provider {...stores}> <Home/> </Provider> ); } } export default App;
如上,簡單的一種引用方式。next 改造同方案二。github
因爲在我項目中,各個模塊不耦合,路由間不想幹,因此各自處理就ok。
ssr 中要解決的一個很大的問題就是 server 和 client 之間狀態同步的問題。以下:vuex
// with-mobx-state.js import React from "react"; import { Provider } from "mobx-react"; export default (initializeStore, storeName, initState = {}) => App => { const isServer = typeof window === "undefined"; // cache function getOrCreateStore(initialState = initState) { if (isServer) { return initializeStore(isServer, initialState); } if (!window[storeName]) { window[storeName] = initializeStore(isServer, initialState); } return window[storeName]; } return class AppWithMobx extends React.Component { static async getInitialProps(ctx) { const mobxStore = getOrCreateStore(); ctx.mobxStore = mobxStore; let appProps = {}; if (typeof App.getInitialProps === "function") { appProps = await App.getInitialProps.call(App, ctx); } return { ...appProps, initialMobxState: mobxStore }; } constructor(props) { super(props); // sync this.mobxStore = getOrCreateStore(props.initialMobxState); } render() { const store = { [storeName]: this.mobxStore }; return ( <Provider {...store}> <App {...this.props} {...store} /> </Provider> ); } }; }; // testStore.js import { action, observable } from "mobx"; // 注意模塊內變量的做用範圍: 模塊內是全局的,模塊間是獨立的 let store = null; class Store { @observable lastUpdate; @observable light = false; constructor(isServer, lastUpdate) { this.lastUpdate = lastUpdate; } @action start = () => { this.timer = setInterval(() => { this.lastUpdate = Date.now(); this.light = true; }, 1000); }; stop = () => clearInterval(this.timer); } export default function initializeTestStore( isServer, { lastUpdate = Date.now() } ) { if (isServer) { return new Store(isServer, lastUpdate); } else { if (store === null) { store = new Store(isServer, lastUpdate); } return store; } } // test.js import React, { Component } from "react"; import { Card, Button } from "antd"; import { inject, observer } from "mobx-react"; import moment from "moment"; import withMobxStore from "../../decorators/with-mobx-store"; import initializeTestStore from "./testStore"; @withMobxStore(initializeTestStore, "testStore") class MobxTest extends Component { static async getInitialProps(ctx) { return { title: "mobx test", PageHeaderVisible: true }; } render() { return ( <Card title="I'm parent"> <TestChild1 /> <TestChild2 /> </Card> ); } } export default MobxTest; @inject("testStore") @observer class TestChild1 extends Component { render() { const { testStore = {} } = this.props; return ( <Card title="I'm child1"> <code>{JSON.stringify(testStore)}</code> <br /> <br /> <Button onClick={testStore.start}>start</Button> </Card> ); } } @inject("testStore") @observer class TestChild2 extends Component { render() { const { testStore } = this.props; console.log("testStore.lastUpdate", testStore.lastUpdate); return ( <Card title="I'm child2" style={{ marginTop: 20 }}> {/*<code>{testStore.lastUpdate}</code>*/} <br /> <br /> <Button onClick={testStore.stop}>stop</Button> <p>{moment(testStore.lastUpdate, "x").format("YYYY-MM-DD HH:mm:ss")}</p> </Card> ); } }
留有問題:上邊initState
實際上是沒有意義的。
解決方案: 沒想到。求大佬指教。npm