Pure javaScript function

There is a concept called pure functions in functional programming, and JavaScript fits the paradigm of functional programming, so there is also the concept of pure functions.

Wikipedia definition of a pure function:

In programming, a function is called pure if it meets the following conditions:

  • This function needs to produce the same output at the same input value. The output of a function is independent of any hidden information or state other than the input value, or of the external output generated by the I/O device.
  • This function cannot have semantically observable function side effects, such as “firing events,” making output devices output, or changing the contents of objects other than output values.

The above definition would be too obscure, so I’ll summarize it briefly:

  • A certain input must produce a certain output;
  • During the execution of the function, there should be no side effects;

So let’s see if some functions are pure:

  • Case 1:

The following function is a pure function; Its output depends on our input without any side effects;

  • Case 2:

The add function is not a pure function; The function depends on an external variable. When the variable changes, it will affect: a certain input produces a certain output; Can I improve it to a pure function? const foo = 5; Can be

Of course, there are many variations of pure functions, but we only need to understand their core. Why are pure functions important in functional programming?

  • Because you can write and use at ease;
  • You write functions that are pure and just implement your own business logic, without caring about incoming content or relying on other external variables;
  • When you use it, you are sure that your input content will not be tampered with arbitrarily, and that the input you determine will have a certain output;

React is very flexible, but there is a strict rule that all React components must protect their props from changing as pure functions do

Why redux

Javascript-developed applications have become increasingly complex:

  • JavaScript has more and more complex states to manage;
  • These states include data returned by the server, cached data, data generated by user operations, and so on. They also include UI states such as whether certain elements are selected, whether loading activity is displayed, and the current page page.

Managing ever-changing states is very difficult:

  • There will be mutual dependence between states, the change of a state will cause the change of another state, the View page may also cause the change of state;
  • When an application is complex, it becomes difficult to control and track when, for what reason, and how state changes;

React helps with the DOM rendering process at the view level, but State is still left to manage ourselves:

  • Whether a component defines its own state, or communication between components is passed through props; It also includes sharing data through Context;
  • React is mainly responsible for helping us manage views, and it is ultimately up to us to decide how to maintain state.

Redux is a container that helps us manage State: Redux is a JavaScript State container that provides predictable State management; In addition to Redux working with React, it can also be used with other interface libraries (such as Vue) and is very small (only 2KB including dependencies).

The core concept of Redux

store

The core concept of Redux is very simple. Let’s say we have a list of friends to manage:

  • If we do not define a uniform specification to operate on this piece of data, then the change of the entire data cannot be tracked;
  • For example, a piece of data is added somewhere on the page via products.push;
  • For example, another page modified a data item with products[0].age = 25;

The entire application is so convoluted that when a bug occurs, it’s hard to track exactly what’s changed;

action

Redux asks us to update the data via action:

  • All data changes must be updated with dispatch actions;
  • Action is a plain JavaScript object that describes the type and content of the update;

For example, here are some updated friends actions:

  • The advantage of mandatory action is that you can clearly know what changes have taken place in the data, and all data changes are traceable and predictable.
  • Of course, currently our actions are fixed objects. In real applications, we would define them by functions that return an action;

reducer

But how do you tie state and action together? The answer is reducer

  • Reducer is a pure function;
  • What the Reducer does is combine incoming state and action to create a new state.

Redux’s three principles

  • Single data source

The state of the entire application is stored in an object tree, and the object tree is stored in only one store; Redux doesn’t force us not to create multiple stores, but that’s not good for data maintenance; A single data source makes state for the entire application easy to maintain, track, and modify;

  • State is read-only

The only way to change State must be to trigger an action, and do not attempt to change State in any other way elsewhere: this ensures that no View or network request can change State directly, they can only describe how they want to change State through action; This ensures that all changes are centralized and executed in a strict order, so there is no need to worry about race conditions;

  • Use pure functions to perform modifications

Link the old state and actions together using the Reducer and return a new state. As the complexity of the application increases, we can divide reducer into several small reducers to operate parts of different state trees respectively. However, all reducer should be pure functions and should not produce any side effects.

How to use Redux

To install redux, run the following command: NPM install redux –save or YARN add redux

1. Create an object as the state we want to save:

2. Create Store to Store this state

  • Reducer must be created when creating a store.
  • Get the current state by using store.getState

3. Use action to modify state

  • Dispatch action via Dispatch;
  • Actions usually have a type attribute and can carry other data as well;

4. Modify the processing code in the Reducer

  • Reducer is a pure function and does not need to modify state directly.

5. You can monitor store changes before sending out actions:

Redux structure partition

If all the logical code is written together, the code becomes difficult to maintain when redux becomes complex.

Next, we split the code, splitting store, Reducer, Action, and Constants into individual files.

constants.js

actionCreator.js

reducer.js

index.js

Redux official figure

The react – use redux

It’s important to note that Redux is not directly related to React, though that said, redux works better with react or Deku libraries because they use the state function to describe interface states, and Redux can send state updates to react to them. Redux officially helped us to provide the React-Redux library, which can be directly used in the project, and the implementation logic will be more rigorous and efficient.

NPM install react-redux

React-redux provides two core apis:

  • The Provider: provide store
  • Connect: Used to connect container components and presentation components

provider

According to the single Store principle, it usually only appears at the top level of the entire application. First, we need to deconstruct the Provider in react-Redux, nest a layer of Provider on the App root component, and pass it into store, which creates a repository for redux.createstore that stores global data.

connect

Syntax format:

connect(mapStateToProps? , mapDispatchToProps? , mergeProps? , options?) (component)`

Generally speaking, only the first two are used, which are used:

  • Convert the state of store.getState() to props for the presentation component
  • Translate actionCreators into a method for presenting component props

Lay special emphasis on: The second parameter on the website is mapDispatchToProps, which is essentially actionCreators. As long as there is a Provider component on top and a Store is available, then any descendant component that wants to use the state in store, Both can be connected using the Connect method. If you just want to connect to actionCreators, you can pass the first parameter as null

Component for asynchronous operations

In real development, a lot of the data stored in REdux might come from the server, and we would need to make asynchronous requests to save the data to Redux. Network requests can be sent in the Class component’s componentDidMount, so we can have a structure like this:

In fact, the data requested by the network is part of our state management, and a better way would be to hand it over to Redux as well.

But how can you operate asynchronously in Redux? The answer is to use Middleware. Middleware allows you to embed code between requests and responses for actions such as cookie parsing, logging, file compression, etc.

Understanding middleware

Redux also introduced the concept of Middleware:

  • The purpose of the middleware is to extend some of its own code between the actions of the dispatch and the reducer finally achieved;
  • Such as logging, calling asynchronous interfaces, adding code debugging capabilities, and so on;

All we need to do now is send asynchronous network requests, so we can add the corresponding middleware: redux-Thunk is the recommended middleware for this demo;

How does redux-Thunk allow us to send asynchronous requests?

Dispatch (Action) by default, the action needs to be a JavaScript object; Redux-thunk allows dispatch(action function), which can be a function;

  • This function is called and passed a dispatch function and a getState function;
  • The dispatch function is used to dispatch the action again later;
  • The getState function allows us to retrieve some of the previous states in consideration of the fact that some of our subsequent operations will depend on the original state.

How do I use redux-thunk

1. Install the story – thunk

Installation command: yarn add redux-thunk

2. The Enhance function of Middleware is passed in when a store is created

Using applyMiddleware to combine multiple Middleware and return an enhancer;

Pass enhancer as the second argument to createStore;

3. Define an action that returns a function:

Note: this is not returning an object, but a function; This function is executed after dispatch;

Reducer code Split

Let’s first understand why this function is called reducer.

If the current reducer has both counter code and home page data; The counter related state or home related state will become more complicated later; We will also continue to add other related states, such as shopping cart, categories, playlists, etc. If all states are managed in a Reducer, as the project becomes increasingly large, it is bound to cause bloated code and difficult to maintain.

Therefore, we can split reducer:

  • We first extract a Reducer for counter processing;
  • Then extract a Reducer for home processing;
  • Combine them;

At present, we have divided different state processing into different reducer, and we thought:

Although it has been placed in different functions, the processing of these functions is still in the same file, the code is very messy;

In addition, constant and action used in reducer are still in the same file; Directory structure:

CombineReducers function

Our current way of merging is to return a new object each time the Reducer function itself is called.

In fact, Redux provides us with a combineReducers function that allows us to merge multiple reducer easily:

So how is combineReducers implemented?

In fact, it also merges the reducers we passed into an object and finally returns a combination function (equivalent to our previous reducer function). During the combination function, it determines whether to return the previous state or the new state by determining whether the same data is returned. The new state triggers the corresponding refresh of the subscriber, while the old state effectively prevents the refresh of the subscriber