1. Remove store and monitor data changes

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>The Redux architecture pattern</title>
    <style type="text/css">
    </style>
</head>

<body>
    <div id='title'></div>
    <div id='content'></div>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
    $(function() {
        function createStore(state, stateChanger) {
            const listeners = []
            const subscribe = (listener) = > listeners.push(listener)
            const getState = () = > state
            const dispatch = (action) = > {
                stateChanger(state, action)
                listeners.forEach((listener) = > listener())
            }
            return { getState, dispatch, subscribe }
        }

        function renderApp(appState) {
            renderTitle(appState.title)
            renderContent(appState.content)
        }

        function renderTitle(title) {
            const titleDOM = document.getElementById('title')
            titleDOM.innerHTML = title.text
            titleDOM.style.color = title.color
        }

        function renderContent(content) {
            const contentDOM = document.getElementById('content')
            contentDOM.innerHTML = content.text
            contentDOM.style.color = content.color
        }

        let appState = {
            title: {
                text: 'the React. Js books'.color: 'red',},content: {
                text: 'React. Js Little book contents'.color: 'blue'}}function stateChanger(state, action) {
            switch (action.type) {
                case 'UPDATE_TITLE_TEXT':
                    state.title.text = action.text
                    break
                case 'UPDATE_TITLE_COLOR':
                    state.title.color = action.color
                    break
                default:
                    break}}const store = createStore(appState, stateChanger)
        store.subscribe(() = > renderApp(store.getState())) // Listen for data changes

        renderApp(store.getState()) Render the page for the first time
        store.dispatch({ type: 'UPDATE_TITLE_TEXT'.text: 'React.js Little Book' }) // Modify the header text
        store.dispatch({ type: 'UPDATE_TITLE_COLOR'.color: 'blue' }) // Change the title color
    })
    </script>
</body>

</html>
Copy the code

 

2. Objects with shared structures improve performance

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>The Redux architecture pattern</title>
    <style type="text/css">
    </style>
</head>

<body>
    <div id='title'></div>
    <div id='content'></div>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
    $(function() {
        function createStore(state, stateChanger) {
            const listeners = []
            const subscribe = (listener) = > listeners.push(listener)
            const getState = () = > state
            const dispatch = (action) = > {
                state = stateChanger(state, action) // Overwrite the original object
                listeners.forEach((listener) = > listener())
            }
            return { getState, dispatch, subscribe }
        }

        function renderApp(newAppState, oldAppState = {}) { // oldAppState = {}
            if (newAppState === oldAppState) return // Render without data changes
            console.log('render app... ')
            renderTitle(newAppState.title, oldAppState.title)
            renderContent(newAppState.content, oldAppState.content)
        }

        function renderTitle(newTitle, oldTitle = {}) {
            if (newTitle === oldTitle) return // Render without data changes
            console.log('render title... ')
            const titleDOM = document.getElementById('title')
            titleDOM.innerHTML = newTitle.text
            titleDOM.style.color = newTitle.color
        }

        function renderContent(newContent, oldContent = {}) {
            if (newContent === oldContent) return // Render without data changes
            console.log('render content... ')
            const contentDOM = document.getElementById('content')
            contentDOM.innerHTML = newContent.text
            contentDOM.style.color = newContent.color
        }

        let appState = {
            title: {
                text: 'the React. Js books'.color: 'red',},content: {
                text: 'React. Js Little book contents'.color: 'blue'}}function stateChanger(state, action) {
            switch (action.type) {
                case 'UPDATE_TITLE_TEXT':
                    return { // Build a new object and return it. state,title: {
                            ...state.title,
                            text: action.text
                        }
                    }
                case 'UPDATE_TITLE_COLOR':
                    return { // Build a new object and return it. state,title: {
                            ...state.title,
                            color: action.color
                        }
                    }
                default:
                    return state // No modification, return the original object}}const store = createStore(appState, stateChanger)
        let oldState = store.getState() // Cache the old state
        store.subscribe(() = > {
            const newState = store.getState() // Data may change, get new state
            renderApp(newState, oldState) // Pass the old and new states to render
            oldState = newState // After rendering, the new newState becomes the old oldState, waiting for the next data change to re-render
        })

        renderApp(store.getState()) Render the page for the first time
        store.dispatch({ type: 'UPDATE_TITLE_TEXT'.text: 'React.js Little Book' }) // Modify the header text
        store.dispatch({ type: 'UPDATE_TITLE_COLOR'.color: 'blue' }) // Change the title color
    })
    </script>
</body>

</html>
Copy the code

3.reducer

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>The Redux architecture pattern</title>
    <style type="text/css">
    </style>
</head>

<body>
    <div id='title'></div>
    <div id='content'></div>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
    $(function() {
        function createStore(reducer) {
            let state = null
            const listeners = []
            const subscribe = (listener) = > listeners.push(listener)
            const getState = () = > state
            const dispatch = (action) = > {
                state = reducer(state, action) // Overwrite the original object
                listeners.forEach((listener) = > listener())
            }
            dispatch({}) // Initialize state
            return { getState, dispatch, subscribe }
        }

        function renderApp(newAppState, oldAppState = {}) { // oldAppState = {}
            if (newAppState === oldAppState) return // Render without data changes
            console.log('render app... ')
            renderTitle(newAppState.title, oldAppState.title)
            renderContent(newAppState.content, oldAppState.content)
        }

        function renderTitle(newTitle, oldTitle = {}) {
            if (newTitle === oldTitle) return // Render without data changes
            console.log('render title... ')
            const titleDOM = document.getElementById('title')
            titleDOM.innerHTML = newTitle.text
            titleDOM.style.color = newTitle.color
        }

        function renderContent(newContent, oldContent = {}) {
            if (newContent === oldContent) return // Render without data changes
            console.log('render content... ')
            const contentDOM = document.getElementById('content')
            contentDOM.innerHTML = newContent.text
            contentDOM.style.color = newContent.color
        }

        function reducer (state, action) {
          if(! state) {return {
              title: {
                text: 'the React. Js books'.color: 'red',},content: {
                text: 'React. Js Little book contents'.color: 'blue'}}}switch (action.type) {
            case 'UPDATE_TITLE_TEXT':
              return {
                ...state,
                title: {
                  ...state.title,
                  text: action.text
                }
              }
            case 'UPDATE_TITLE_COLOR':
              return {
                ...state,
                title: {
                  ...state.title,
                  color: action.color
                }
              }
            default:
              return state
          }
        }

        const store = createStore(reducer)
        let oldState = store.getState() // Cache the old state
        store.subscribe(() = > {
            const newState = store.getState() // Data may change, get new state
            renderApp(newState, oldState) // Pass the old and new states to render
            oldState = newState // After rendering, the new newState becomes the old oldState, waiting for the next data change to re-render
        })

        renderApp(store.getState()) Render the page for the first time
        store.dispatch({ type: 'UPDATE_TITLE_TEXT'.text: 'React.js Little Book' }) // Modify the header text
        store.dispatch({ type: 'UPDATE_TITLE_COLOR'.color: 'blue' }) // Change the title color
    })
    </script>
</body>

</html>
Copy the code

Before you knew it, not only had you mastered Redux, but you had written it yourself. We started with a very raw code and worked our way through problem finding, problem solving, and code optimization, until we came up with the Redux pattern on our own. This is called the Redux pattern, so let’s go over what we did in these sections.

We learned from a simple example of code that shared states can behave very unpredictably if they can be arbitrarily modified, so we raised the bar for modifying data: you must perform certain permitted changes through dispatches, and you must explicitly declare them in actions.

This pattern works well, so let’s abstract it out as createStore, which generates a Store and contains getState and Dispatch functions for us to use.

As it turned out that manually rerendering every time we changed the data was cumbersome, we wanted to rerender the view automatically. So we added the subscriber mode, which allows you to subscribe to the store. Subscribe data modification event, and automatically re-render the view every time the data is updated.

Then we discovered that the original “re-render view” had serious performance issues, and we introduced “objects with shared structures” to help us solve this problem, so that simple judgments can be made at the beginning of each render function to avoid re-rendering data that has not been modified.

We optimized stateChanger into reducer, and defined reducer as a pure function, whose function is to take charge of the initial state and calculate the new state with shared structure according to state and action.

CreateStore can now be used directly.

// Set a reducer
function reducer (state, action) {
  /* Initialize state and switch case */
}

/ / store
const store = createStore(reducer)

// Listen for data changes and re-render the page
store.subscribe(() = > renderApp(store.getState()))

Render the page for the first time
renderApp(store.getState()) 

// The page can be automatically updated
store.dispatch(...)
Copy the code