How does Redux work? Can solve those problems
With the complexity of JavaScript single-page application development day trends, managing changing states can be difficult
The emergence of Redux solves the state data problem.
Here I use a recent popular TV series “Home” to do a simple demo. Let me introduce it to you
The story begins to pull!
First of all, there is a client to settle the world housing agency looking for a house, there is a prerequisite agent and the client.
Let’s create a scene create a folder app and create an index.html

<! DOCTYPE html> <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge"</title> </head> <body> <! --> <div id='user_name'></div>
        <div id='user_data'></div> <! <div id='intermediaary'></div>
        <div id='inter_data' ></div id='inter_data'> <! -- storyscript --> <script SRC ="app.js"></script>
    </body>
</html>Copy the code



Next, create our story’s footstep app.js

//1, initialize the data define the role zhang SAN to settle down to find a houselet appStore = {
  user: { name: "Zhang", data: "House hunting" },
  intermediaary: { name: "Home to the world", data: "Room four well reception for housing search"}}; // Output user requirementsfunction renderUser(user) {
  let element = document.querySelector("#user_name"); element.innerHTML = user.name; // User Zhang SAN needs to find an apartmentlet ev = document.querySelector("#user_data"); ev.innerHTML = user.data; } // Requirements for mediation processingfunction renderInermediaay(intermediaary) {
  let element = document.querySelector("#intermediaary");
  element.innerHTML = intermediaary.name;
  let ev = document.querySelector("#inter_data"); ev.innerHTML = intermediaary.data; } // Define the function and print the contentfunctionrenderApp(appStore) { renderUser(appStore.user); renderInermediaay(appStore.intermediaary); } renderApp(appStore); // Execute the scriptCopy the code

Zhang SAN looking for a house to settle down the world square four Wells began to receive, what is the problem here?
State is a global variable, it’s a low-security variable that can be changed anywhere, okay? Increase the threshold of modification can not be arbitrarily changed.
At this point we need an action to create a dispatch function
Three, here we first define the real estate agent can do constant

// define what the broker and user understand const UPDATE_USER_NAME ="UPDATE_USER_NAME"; // The user's name const UPDATE_USER_DATA ="UPDATE_USER_DATA"; // What does the user want to do const UPDATE_INTERMEDIAARY_NAME ="UPDATE_INTERMEDIAARY_NAME"; // The mediation name const UPDATE_INTERMEDIAARY_DATA ="UPDATE_CONTEN_TEXT"; // Action Dispatch action Description What do you want to do? Is a common property that must have onetype
function dispatch(action) {
  switch (action.type) {
    case UPDATE_USER_NAME:
      appStore.user.name = action.name;
      break;
    case UPDATE_USER_DATA:
      appStore.user.data = action.data;
      break;
    case UPDATE_INTERMEDIAARY_NAME:
      appStore.intermediaary.name = action.name;
      break;
    case UPDATE_INTERMEDIAARY_DATA:
      appStore.intermediaary.data = action.data;
      break;
    default:
         throw new Error("I can't do it!); }} // Li Si came to settle down and sell his housesetTimeout(() => {
  dispatch({ type: UPDATE_USER_NAME, name: "Bill" });
  dispatch({ type: UPDATE_USER_DATA, data: "Here to sell the house." });
  dispatch({ type: UPDATE_INTERMEDIAARY_DATA, data: "Prince hospitality for house buyers."}); renderApp(appStore); // Execute the script}, 1000);Copy the code

4. There is a guarantee that the access mediation can only do these four things and nothing else.
So let’s create a function to put the appStore into createStore
1. Put global variables into createStore
2. Dispatch is also put in and created to get the current state functon

// Add a function repositoryfunction createStore() {//1, initialize the data to define the role zhang SAN to find a houselet state = {
    user: { name: "Zhang", data: "House hunting" },
    intermediaary: { name: "Home to the world", data: "Room four well reception for housing search"}}; // Create a method to get the current statefunction getState() {
    returnJSON.parse(JSON.stringify(state)); } //action What do you want to do? Is a common property that must have onetype
  function dispatch(action) {
    switch (action.type) {
      case UPDATE_USER_NAME:
        state.user.name = action.name;
        break;
      case UPDATE_USER_DATA:
        state.user.data = action.data;
        break;
      case UPDATE_INTERMEDIAARY_NAME:
        state.intermediaary.name = action.name;
        break;
      case UPDATE_INTERMEDIAARY_DATA:
        state.intermediaary.data = action.data;
        break;
      default:
        throw new Error("I can't do it!); }}return { getState, dispatch };
}Copy the code



This solves the problem of uncontrollable global variables.


Each application has different processing logic. We cannot put dispatch directly under createStore, otherwise we need to establish multiple state management. This is unnecessary, so we need to further optimize and add a reducer processing function. Add the initialization state of the user.

// Add a function repositoryfunction< reducer > < reducer > < reducer > < reducer > < reducer > < reducerletstate; // Create a method to get the current statefunction getState() {
    returnJSON.parse(JSON.stringify(state)); } //action What do you want to do? Is a common property that must have onetype
  functiondispatch(action) { state = reducer(state, action); } dispatch({}); // Get the initialization statereturn{ getState, dispatch }; } // Add user initialization statuslet initState = {
  user: { name: "Zhang", data: "House hunting" },
  intermediaary: { name: "Home to the world", data: "Room four well reception for housing search"}}; // Add handler: returns new state based on old state processinglet reducer = function(oldState = initState, action) {
  switch (action.type) {
    caseUPDATE_USER_NAME: // Note that a new object must be returnedreturn{... oldState, user: { ... oldState.data, name: action.name } }; //break;
    case UPDATE_USER_DATA:
      return{... oldState, user: { ... oldState.user, data: action.data } };case UPDATE_INTERMEDIAARY_NAME:
      return{... oldState, intermediaary: { ... oldState.intermediaary, name: action.name } };case UPDATE_INTERMEDIAARY_DATA:
      return{... oldState, intermediaary: { ... oldState.intermediaary, data: action.data } }; default: // throw new Error("I can't do it!);
      returnoldState; // Return to old state}};letstore = createStore(reducer); renderApp(store.getState()); // Li Si came to settle down and sell his housesetTimeout(() => {
  store.dispatch({ type: UPDATE_USER_NAME, name: "Bill" });
  store.dispatch({ type: UPDATE_USER_DATA, data: "Here to sell the house." });
  store.dispatch({
    type: UPDATE_INTERMEDIAARY_DATA,
    data: "Prince hospitality for house buyers."
  });
  // console.log(store.getState());
  renderApp(store.getState());
}, 1000);Copy the code





It solves the problem of using it in a variety of environments and then what are the other problems?
RenderApp right now we have to render every time we have to call it manually which is inconvenient,


Add publish subscriptions to update our status automatically to createStore

// Output user requirementsfunction renderUser(user) {
  let element = document.querySelector("#user_name"); element.innerHTML = user.name; // User Zhang SAN needs to find an apartmentlet ev = document.querySelector("#user_data"); ev.innerHTML = user.data; } // Requirements for mediation processingfunction renderInermediaay(intermediaary) {
  let element = document.querySelector("#intermediaary");
  element.innerHTML = intermediaary.name;
  let ev = document.querySelector("#inter_data"); ev.innerHTML = intermediaary.data; Const UPDATE_USER_NAME = const UPDATE_USER_NAME = const UPDATE_USER_NAME ="UPDATE_USER_NAME"; // The user's name const UPDATE_USER_DATA ="UPDATE_USER_DATA"; // What does the user want to do const UPDATE_INTERMEDIAARY_NAME ="UPDATE_INTERMEDIAARY_NAME"; // The mediation name const UPDATE_INTERMEDIAARY_DATA ="UPDATE_CONTEN_TEXT"; // Add a function repositoryfunction createStore(reducer) {
  letlisteners = []; // Store all statesletstate; // Create a method to get the current statefunction getState() {
    returnJSON.parse(JSON.stringify(state)); } //action What do you want to do? Is a common property that must have onetype
  functiondispatch(action) { state = reducer(state, action); listeners.forEach(fn => fn()); } dispatch({}); // Add a subscription mode for external subscription to the changes in the state of the repository, if the state changes to execute the programfunctionsubscribe(listener) { listeners.push(listener); // Add a subscription // Cancel a published subscriptionreturn functionListeners = listeners. () {listeners = listeners. = item; }); }; }return{ getState, dispatch, subscribe }; } // Add user initialization statuslet initState = {
  user: { name: "Zhang", data: "House hunting" },
  intermediaary: { name: "Home to the world", data: "Room four well reception for housing search"}}; // Add handler: returns new state based on old state processinglet reducer = function(oldState = initState, action) {
  switch (action.type) {
    caseUPDATE_USER_NAME: console.log({ ... oldState, user: { ... oldState.user, data: action.data } });return{... oldState, user: { ... oldState.data, name: action.name } };case UPDATE_USER_DATA:
      // state.user.data = action.data;
      // break;
      return{... oldState, user: { ... oldState.user, data: action.data } };case UPDATE_INTERMEDIAARY_NAME:
      return{... oldState, intermediaary: { ... oldState.intermediaary, name: action.name } };case UPDATE_INTERMEDIAARY_DATA:
      return{... oldState, intermediaary: { ... oldState.intermediaary, data: action.data } }; default: // throw new Error("I can't do it!);
      returnoldState; // Return to old state}};letstore = createStore(reducer); // Define the function and print the contentfunction renderApp() { renderUser(store.getState().user); renderInermediaay(store.getState().intermediaary); } renderApp(); // Add a subscription store.subscribe(renderApp); // Li Si came to settle down and sell his housesetTimeout(() => {
  store.dispatch({ type: UPDATE_USER_NAME, name: "Bill" });
  store.dispatch({ type: UPDATE_USER_DATA, data: "Here to sell the house."}); // Note that the user does not change the home world intermediary 😁 store.dispatch({type: UPDATE_INTERMEDIAARY_DATA,
    data: "Prince hospitality for house buyers."
  });
}, 1000);Copy the code

Well, our customers can go to our real estate agency to deal with the business of buying and selling real estate is not very simple.