It is not a short time to study state management, and I gradually have my own understanding of the nature of state management. In the realm of state managers, there are two main schools, immutable, represented by Redux, and mutable, represented by Mobx. We prefer immutable for the purity of data flow, but we prefer mutable for the ease of writing code. Based on this subjective intention, the tool immer was born. In a minimalist way, it provides us with a form of state manipulation that is mutable but produces an immutable result, dramatically reducing project complexity in terms of code volume. Redux redux redux redux redux redux redux redux redux redux redux redux redux redux You don’t even need to worry about third-party libraries like Redux-Thunk for asynchronous operations.

The react-Redux interface is almost identical

React-redux is the most well-known state manager connection tool for React developers and has been repeatedly proven to be one of the most effective, so MY approach is almost identical to that of React-Redux. Let’s look at its most direct use:

import { createStore, Provider } from 'react-immut'

const store = createStore({
  name: 'timy'.age: 10,})export function App() {
  return (
    <Provider store={store}>.</Provider>)}Copy the code

This is the skeleton code for our entire application. The difference with Redux is that we don’t need to write a lot of reducer code, we just need to pass in the initial state, and because of this, our code volume was instantly reduced by countless lines.

In specific components, we also use Connect to connect.

import { connect } from 'react-immut'

const mapStateToProps = (state) = > {
  const { name, age } = state
  return { name, age }
}

const mapDispatchToProps = (dispatch) = > {
  // Dispatch is completely different from react-redux
  const changeName = (name) = > dispatch('name', name)
  const changeAge = (age) = > dispatch('age', age)
  // Unlike react-redux, react-immut does not actively inject dispatches into components
  return { changeName, changeAge }
}

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)

function MyComponent(props) {
  const { name, age, changeName, changeAge } = props
  // ...
}
Copy the code

So far, at the code level, it’s pretty easy to understand without any difficulty.

Magic dispatch method

Unlike Redux with dispatch actions, React-Immut’s dispatch is a magical way to achieve a minimalist programming experience. Code red has already seen the convenience of Dispatch. Now, we’re going to see something amazing happen.

dispatch(keyPath, value)

The keyPath here is not just a property name, but a property path. Let’s see how it works:

dispatch('parent.child'.'new value')
dispatch('books[0].title'.'new title')
dispatch(['root', symbol], Symbol())
Copy the code

You see, it takes so many forms.

dispatch(keyPath, prev => next?)

The second argument is a function that takes the current value and returns the new value. This is fun. We can play with a lot of ideas.

dispatch('name'.name= > {
  return name === 'tomy' ? name : 'gage'
})
dispatch('some'.some= > {
  some.child.name = 'some'
  some.child.age = 10
  // Does not return any value
})
Copy the code

Something different has finally happened. Here, the red code is particularly obtrusive, and we wouldn’t allow it in a traditional immutable system, but in react-immut, it’s the best way to write it. Think about it. In the old days, to be immutable, you might have had to do this:

dispatch('some'.some= > {
  return {
    ...some,
    child: {
      ...some.child,
      name: 'some'.age: 10,}}})Copy the code

Look, what a hassle. A few more layers, mixing objects and arrays, would be a maddening operation. However, with immer, you just need to write the same code as in the previous example, and modify the value of the object properties directly. In the end, the state you get is immutable, so you can use it without modifying the object.

dispatch(prev => next?)

Without passing keyPath, you can get the state of the entire application directly.

dispatch(state= > {
  state.name = 'tomy'
})
Copy the code

It is critical to return next. If next is returned, prev is replaced with next, but it must be noted that the data type of next and prev must always be ‘object’. Immer’s best practice, on the other hand, is not to return anything, not to return anything, which gives us a better idea of what values have been modified.

The use of Hooks

It’s 2020. Hooks, of course. Use the hooks method useStore to omit the connect step and simplify the code.

import { useStore } from 'react-immut'

function MyComponent() {
  const [state, dispatch] = useStore() // Get the state and dispatch methods for the entire application
}
Copy the code

Note that useStore is context-based, which means you must use useStore inside your Provider. This way to get global state, do not need to connect at all, does not feel flying?

Combined Store

In many cases, we often partition our state, and each individual partition is called a namespace. We tend to organize all the code files related to a business component under the same folder, which helps us better manage all the code related to the same business component. To facilitate this scenario, we provide a Combine Store that organizes global state through namespace.

// components/a-some/store.js
export const state = { // state is required
  name: 'Tom'.age: 10,}export function changeName(dispatch, name) { // Define some methods
  dispatch(state= > { // This state refers to the local state, not the global state, that is, within the file, you can only change the state of the namespace, not the other Spaces
    state.name = name
  })
}

export function changeAge(dispatch, age) {
  dispatch(state= > {
    state.age = age
  })
}
Copy the code

Next, we use this defined file

// app.js
import { createStore } from 'react-immut'
import * as Asome from './components/a-some/store.js'

// Pass the second argument as follows
const store = createStore(null, {
  Asome, // Use 'Asome' as the namespace name
  // Other namespaces can be introduced here
})

export default function App() {
  return (
    <Provider store={store}>.</Provider>)}Copy the code

In a specific component, the namespace is read by key (essentially the same as reading from global state).

function MyComponent() {
  const [{ name, age }, { changeName, changeAge }] = useStore('Asome')
  // ...
}
Copy the code

Combine essentially does two things: it parses structured objects to create stores, and it parses namespace methods to add to Dispatch. Dispatch is a function, but since functions are essentially objects in THE JS language, you can add attributes to the function, so that when combineStore is used, you can add namespace attributes to the function, making it easy for developers to read defined methods.

const mapDispatchToProps = (dispatch) = > {
  const { changeName, changeAge } = dispatch.Asome
  return { changeName, changeAge }
}
Copy the code

asynchronous

The biggest difference from Redux is that we do not have reducer, so our operations on state are externally implemented rather than internally defined by the store. As soon as we can call dispatch, we can change the state. Therefore, asynchronous operations are too simple.

export function saveName(dispatch, name) {
  fetch('... ', { method: 'POST'.body: JSON.stringify({ name }) })
  	.then(res= > res.json())
    .then(data= > {
      dispatch(state= > {
        state.name = data.name
      })
    })
}
Copy the code

Dispatch can be invoked to achieve this effect, either inside a component, in the mapDispatchToProps function of Connect, or in a namespace defined method.

conclusion

React-immut takes advantage of the power of immer to implement extremely convenient global status updates. React-immut has the same design as React-Redux, allowing developers to switch without too much barrier. Also, its source code is only about 150 lines, no complicated magic, written in a down-to-earth way, you can read the source code here. By using immutable, we can do almost anything Redux can do, such as time travel. Why do we need Redux when we no longer need boilerplate code?


Original address:www.tangshuang.net/7852.html

Author: Fuzige

Wechat official id: wwwtangshuangnet