The premise

In previous projects, mobx was generally used for data state management. In this paper, react Hook was used to implement state management, and the similarities and differences between the old and new methods were compared. Everything that follows in this article is in the context of the React project. Corrections and additions are welcome.Copy the code

Mobx

A quick introduction to Mobx, as you can see from left to right: 1 There are and only actions that can be used to change the state, and a change in the state will cause a change in the calculated properties (if any). 2 A change in the calculated properties will cause reaction to be triggered, with side effects such as updating the UICopy the code

why Mobx

There are several reasons for using mobx instead of setState in our project (personal understanding). 1 setSate is not a synchronous operation, when we modify the state data through setState, the following logic immediately takes the old value, and the new value of state will be obtained in the next render. 2 If all data is stored in state, then asynchronous requests such as timers returning data that is not actually relevant to UI rendering can also cause components to perform unnecessary re-renders. 3 setState Is not suitable for managing global status.Copy the code

Mobx state management instance

The use of Mobx is also very simple: 1 install mobx related NPM 2 declare a store class to store the data we needCopy the code
import { action, computed, observable } from "mobx"
class Store {
    // Observed, you can think of as State in Vuex, that is, declare some State you want to observe, variables.
    // The observed can be: JS primitive data types, reference types, ordinary objects, class instances, arrays, and mappings
    @observable public num: number = 0;
    
    @computed
    public get addNum() {
        // ...
    }
    
    // Change the observed using @action
    @action.bound
    public add() {
        // ...}}Copy the code
Inject all stores with the provider at the top level, use inject responded data where it needs to listen for changes, and transform the component into an observer using the @obServerble modifier before the component is declared, refreshing the component whenever any data it depends on changes.Copy the code
@inject("store") 
@observer   
class Example extends React.Component<{},{}> {
   public render() {
        return (
            <h1>{this.props.store! .num}</h1>)}}Copy the code
Similar to a store property that uses a @computed declaration, components decorated with @Observer will automatically rebuildCopy the code

React components are (despite their name) not reactive out of the box. The @observer decorator from the mobx-react package fixes that by wrapping the React component render method in autorun, automatically keeping your components in sync with the state.

Those of you who are interested can use this simple exampleCopy the code

React -jsfidder open – simple example of mobx in react

And this ten minute introduction to MOBxCopy the code

Mobx.js.org/getting-sta…

React Hook for global state management

1 new contextCopy the code
const StateContext = createContext();
Copy the code
2 Set the value of statecontext. Provider to useReducerCopy the code
const StateProvider = ({ reducer, initialState, children }) = > (
  <StateContext.Provider value={useReducer(reducer, initialState)} >
    {children}
  </StateContext.Provider>
);
Copy the code
3 When dispath was used by children to trigger reducer, the value of Context was changed and the value of StateContext was updated. This results in the update of the components, which implements the data transfer of the context reducer -> Action ->state- state dependent component updatesCopy the code

If you’re interested, check out this online demo

Codesandbox. IO/s/sharp – cor…

Mobx-react-lite is a state management tool based on hook extension

The state is also managed inside the Observable, but instead of injecting the store, it is managed by the context

github

React Hook state management in SSR

There are a few differences to note in moving from a class component to a function component

1 Static properties of getInitialProps class ->function Properties of the componentCopy the code
Page.getInitialProps = async ctx => {
  const res = await fetch('https://api.github.com/repos/zeit/next.js')
  const json = await res.json()
  return { stars: json.stargazers_count }
}
Copy the code
2. In the original class component, Store can inherit baseStore. In baseStore, initState is passed to realize state synchronization at both ends of CS. In the _app. TSX constructor, NEXT_DATA is used to get the data that getInitialProps got on the server.Copy the code
static async getInitialProps(appContext: AppContext): Promise<any> {
    return {
        test:test
    }
}
// prop corresponds to the data returned by getInitialProps
  constructor(props: any) {
    super(props) <! Test_test_test_test_test_test_test_test_test_testconsole.log(props.test)
  }
Copy the code
Use it as the context for the initial value, which is the same as the actual render result of the page. The react built-in diff algorithm doesn't make any difference. You won't see any noticeable changes to the page.Copy the code

conclusion

1 Use context API + useReducer to complete most state management requirements, which is suitable for projects with simple global status.

Mobx introduced mobx-React Lite, which uses context for state management and is lighter than the original mobx-React implementation (react 16.8.0+ only).

Refer to the article

Mobx.js.org/getting-sta… 10 minutes to get started with Mobx

Medium.com/simply/stat… React + Hook state management

Zh-hans.reactjs.org/docs/contex… react Context Api