• The Inside story of Redux
    • A bloodbath caused by a question
    • rally
    • Basic understanding of
    • Keep out appearance repaired
    • In doubt
    • Not to stay up
  • A link to the

The Inside story of Redux

A bloodbath caused by a question

During the interview, the interviewer asked: “Look at your resume, you use Vue and React. Can you tell the difference?” “And then blah-blah-blah-blah-blah-blah, blah! When I answered Vuex and Redux, the interviewer asked, why does Redux always return a new state? Why not go back to the old state? Needless to say, the interview results were GG.

rally

After half a month, when I summarized my interview experience, I read the source code of Redux again, OJBK, and then went to Github to see some big brothers’ interpretation, and then summed up a column, for my future review

Basic understanding of

What is a Redux?

Redux is a JavaScript state container that provides predictable state management solutions, as described on the website:

  // Redux is a predictable state container for JavaScript apps.
Copy the code

So what can it do?

  // It helps you write applications that behave consistently, run in different environments (client, server, and native) and are easy to test.
  // On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.
Copy the code

The three principles

  • Single data source: The state of the entire application is stored in a single State Tree and exists in a single store

  • State is read-only: the only way to change state is to trigger an action and then dispatch via the action’s type. You cannot change the state of the application directly

  • State changes are all done by pure functions: To describe how an action changes the state tree, you need to write reducers

Keep out appearance repaired

Let’s first learn about Store, Middleware, Action, reducer and so on

store

The store here is generated by the createStore(Reducers, preloadedState, enhancer) method provided by Redux. As you can see from the function signature, you must pass in the reducers to generate the Store, and you can also pass in the initialization state (preloadedState) as a second optional parameter. The third parameter is usually applyMiddleware(thunkMiddleware)

  import { createStore, applyMiddleware } from 'redux'
  import thunkMiddleware from 'redux-thunk' // redux-thunk is used here

  const store = createStore(
    reducers,
    state,
    applyMiddleware(thunkMiddleware) // applyMiddleware first receives thunkMiddleware as an argument, and the two are combined to form a new function (enhance)
  )
Copy the code

The core API in Redux is createStore. The store created by the createStore method is an object that contains four methods:

  • GetState () : Gets the current state of the store.

  • Dispatch (Action) : Dispatch an action and return the action. This is the only way to change the data in the store.

  • Subscribe (listener) : Registers a listener that is called when the store changes.

  • ReplaceReducer (nextReducer) : Updates the reducer in the current store. This reducer is usually called only in the development mode.

middleware

The following figure shows a simple synchronous data flow scenario in Redux. After the button is clicked, an action is distributed in the callback. After the Reducer receives the action, the state is updated and the view is notified to re-render.

One-way data flow, looks fine. However, if every action needs to be printed for debugging, the dispatch or Reducer implementation needs to be modified to print logs.

For another example, after clicking button, we need to request data from the server first, and only after the data is returned, we can re-render the view. At this time, we hope dispatch or Reducer have the function of asynchronous request. Another example is the asynchronous request for data to return, print a log, request the data, print the log, and render.

In the face of diverse business scenarios, it is obviously not universal to simply modify the code of dispatch or reducer. Redux draws lessons from the idea of middleware in Node.js Koa, while Reducer in Redux cares more about data transformation logic. So Middleware was created to enhance dispatch.

Action

  // Refer to the introduction of the official website

  // Actions are payloads of information that send data from your application to your store. 
  // They are the only source of information for the store
  // You send them to the store using store.dispatch().
Copy the code

Action is the payload that transfers data from the app to the Store. It is the only source of store data. Simply put, an Action is a message type that tells Redux what it is time to do and sends the data to Redux internally.

Action is a simple object. The Reducer must have a Type attribute, which indicates the Action type (determine the logic to be executed). Other attributes can be customized by the reducer. Such as:

  const START_FETCH_API = 'START_FETCH_API'
Copy the code
  {
    type: START_FETCH_API,
    data: {
      id: itemId,
      value: 'I am Value'}}Copy the code

Action Creator

Check out the introduction on the official website: Action Creator is exactly that — functions that create actions. It’s easy to conflate the terms “Action” and “Action” Creator “, so do your best to use the proper term. In other words: The Action Creator in Redux simply returns an Action

  function fetchStartRequestApi(jsondata) {
    return {
      type: START_FETCH_API,
      data: jsondata
    }
  }
Copy the code

As we know, Redux evolved from Flux, in which Action Creators were called and often triggered a Dispatch. Such as:

  function fetchStartRequestApiDispatch(jsondata) {
    const action = {
      type: START_FETCH_API,
      data: jsondata
    }
    dispatch(action)
  }
Copy the code

In Redux, however, we only needed to send the results returned by Action Creators to Dispatch (), completing the process of launching a Dispatch and even creating a bound Action Creators for automatic dispatch

  // example 1
  dispatch(fetchStartRequestApi(jsondata))

  // example 2
  const boundFetchStartRequestApiDispatch = jsondata= > dispatch(fetchStartRequestApi(jsondata))
Copy the code

Somebody’s about to faint. What’s dispatch? The store object created by createStore() has a method: Dispatch (action), the store can call the dispatch() method directly through store.dispatch(), but most of the time we will use the connect() helper provided by React-Redux. BindActionCreators () can automatically bind multiple action creator functions to the Dispatch () method.

Reducers

  // Refer to the introduction of the official website

  // Reducers specify how the application's state changes in response to actions sent to the store. 
  // Remember that actions only describe what happened, but don't describe how the application's state changes
Copy the code

As mentioned above, Reducers must be a pure function that handles state updates based on actions and returns the old state if no updates are made or an unknown action is encountered. Otherwise return a new state object. You can also use the object. assign function to create a new state. __ specific why, we read the source when we know ~

Never do these things in a Reducer:

  • Modify the passed parameter;

  • Perform operations that have side effects, such as API requests and route jumps;

  • Call impure functions, such as date.now () or math.random ();

Below the last example code, help digest, send a request, get the music list

  // action.js

  /* * Action type */  
  export const START_FETCH_API = 'START_FETCH_API'
  export const STOP_FETCH_API = 'STOP_FETCH_API'
  export const RECEIVE_DATA_LIST = 'RECEIVE_DATA_LIST'
  export const SET_OTHER_FILTERS = 'SET_OTHER_FILTERS'

  /* * Other constants */
  export const otherFilters = {
    SHOW_ALL: 'SHOW_ALL'.SHOW_ACTIVE: 'SHOW_ACTIVE'
  }

  /* * action creates the function */
  export function startFetchApi() {
    return {
      type: START_FETCH_API
    }
  }

  export function stopFetchApi() {
    return {
      type: STOP_FETCH_API
    }
  }

  export function receiveApi(jsondata) {
    return {
      type: RECEIVE_DATA_LIST,
      data: jsondata
    }
  }

  export function setOtherFilters (filter) {
    return {
      type: SET_OTHER_FILTERS,
      data: filter
    }
  }

  / / asynchronous
  export const fetchMusicListApi = (music_id) = > dispatch => {
    dispatch(startFetchApi())
    fetch({
      url: url,
      method: 'POST'.data: {
        music_id: music_id
      }
    }).then((res) = > {
      dispatch(stopFetchApi())
      dispatch(receiveApi())
    }).catch((err) = > {
      console.log(err)
    })
  }
Copy the code
  // reducers.js
  
  / / into the action. Js
  import { otherFilters } from './action'

  / / the initial state
  const initialState = {
    otherFilters: otherFilters.SHOW_ALL,
    list: [].isFetching: false
  }

  function reducers(state, action) {
    switch(action.type) {
      case SET_OTHER_FILTERS: 
        return Object.assign({}, state, {
          otherFilters: action.payload.data
        })
      case START_FETCH_API:
        return Object.assign({}, state, {
          isFetching: true
        })
      case STOP_FETCH_API:
        return Object.assign({}, state, {
          isFetching: false
        })
      case RECEIVE_DATA_LIST:
        return Object.assign({}, state, {
          list: [ ...action.payload.data ]
        })
      default: 
        return state
    }
  }
Copy the code

Pay attention to

  1. Do not modify state. Create a new copy using object.assign (). Object.assign(state, {otherFilters: action.paypay.data}) cannot be used this way because it changes the value of the first parameter. You must set the first parameter to empty object

  2. Return the old state in default. When encountering an unknown action, always return to the old state.

In doubt

  • How does bindActionCreators() automatically bind my action to Dispatch?

  • What is a pure function?

  • Why must reducer be a pure function?

  • Why can only modify state through action? What’s wrong with modifying state directly?

  • How does bindActionCreators() automatically bind my action to Dispatch?

  • Why does reducers have to return the old state in the case of default?

  • .

Not to stay up

Haven’t finished writing, there are below, just want to understand a bit more in-depth, and then continue to write a summary, the purpose is to give yourself, including the novice to see, hope you big guy, hand, you big guy no interest can skip ~, go directly to github to see the source code ha, portal here: Redux


Update 2019.01.03: Why Redux is returning a new State-triggered murder case (PART 2)

A link to the

  • Story: Chinese documents cn.redux.js.org/docs/basics…

  • Redux: redux.js.org/basics/acti…

  • Making: github.com/PDKSophia/b…