preface

In the process of learning React, I was deeply attracted by the functional programming mode of React. Everything is a component and everything is JavaScript. The React framework has a very simple function, mainly for rendering, but it has a very active community and has developed many excellent libraries and tools. Redux, react-Router, react-router, webpack configuration, es6 syntax, react-router, react-router, react-Router, react-Router, react-Router When components don’t need to be rerendered, next-js server rendered, etc… I always had the idea of reconstructing my blog. I happened to be on vacation during this period and I also happened to learn React, so this project came into being.

Project address: github.com/k-water/rea…

If you feel good, you can click “Star” in the upper right corner to support, thank you! ^_^

Technology stack

The front end

  • react
  • react-redux
  • react-thunk
  • react-router
  • axios
  • eslint
  • maked
  • highlight.js
  • antd
  • es6/7/8

The background

  • spring boot

This project adopts the implementation of the separation of the front and back ends. The back-end interface is designed based on RESTful specifications to only provide data, while the front end is responsible for routing jump, permission restriction, rendering data and so on. PS: Since I’m a front-end ER, this is mainly about the front-end.

Implemented functions

  • [x] admin add delete check change blog
  • [x] Blog tag
  • [X] Blog content markdown
  • [x] Blog content page display directory
  • [x] return to top
  • [x] Markdown code highlight
  • [x] User login registration
  • [x] User comments
  • [x] response type

TODO

  • [] Blog classification
  • [] Click the hashtag to search for related blogs
  • [] Optimize the homepage sidebar
  • [] Perfect archiving
  • [] Deployment online

Results the preview

Home page

Content page

The user login

User comments

Background management

Personal summary

Markdown rendering

There was a bit of a problem with rendering markdown in the front end. There were many packages involved, but the result of parsing each package was different. The community around React recommended react-Markdown, which was also easy to use

import ReactMarkdown from 'react-markdown'

const input = '# This is a header\n\nAnd this is a paragraph'
ReactDOM.render(
    <ReactMarkdown source={input} />,
    document.getElementById('container')
)
Copy the code

However, I found the react-Markdown support for tables unfriendly, so I marked, combined with highlight.js, to highlight the code part

import marked from 'marked'
import hljs from 'highlight.js'
  componentWillMount() {
    marked.setOptions({
      highlight: code= > hljs.highlightAuto(code).value
    })
  }
Copy the code

React doesn’t recommend inserting strings directly into the DOM due to security concerns, but React maintains an API that allows you to do this:

<div className="article-detail" 
  dangerouslySetInnerHTML={{ __html: marked(output)) }} />
Copy the code

The React componentization

The React component consists of a DOM view and state, a data center whose state determines the state of the view. React is only responsible for rendering the UI, and unlike other frameworks that listen for data to dynamically change the DOM, React uses setState to control view updates. SetState will automatically call the render function, triggering the view to be re-rendered, and will not trigger an update if only the state data changes without calling setState. When it comes to components, it’s important to understand the React component lifecycle.

There are many explanations of this section on the Internet, you can look them up. And the one I use the most in development

  • componentWillMount()
  • componentDidMount()
  • ShouldComponentUpdate (nextProps, nextState) shouldComponentUpdate(nextProps, nextStateshouldComponentUpdateAs a result of the articleshouldComponentUpdateThe default returntrueA simple way to determine if a component needs to be rerendered is to compare the data structure before and after the updateimmutable.js.

Component to component communication

React is a one-way data flow, transferring data from top to bottom. There are many ways to address communication between complex components. Parent component communication is usually the simplest. The parent component passes a callback function to the child component, which communicates with the parent component directly by calling this. Props.

If components are deeply nested, you can use the context getChildContext to pass information, so that instead of passing function layers down, any of the layers’ children can be accessed directly through this.context. The internal implementation of React-Redux uses this method.

Sibling components cannot communicate directly with each other and need to use their superiors at the same level as a staging post.

Redux

Redux is not required, if not complex component communication, simple logic, use context. Redux is not specific to React; other frameworks can use Redux as well. It took me a long time to learn Redux. At first, I didn’t understand the middle operation of Redux, but I gradually understood it after reading many articles written by my predecessors. A quick word about Redux. Redux consists of three parts: Store, Reducer, and Action

A store is an object that has three main methods: Dispatches are used for action distribution, and will be executed immediately when an action is sent to the Dispatch. Sometimes we don’t want it to be triggered immediately. We can modify dispatches in createStore using middleware such as redux-thunk. But that’s what React-Radux does. Subscribe is a function that registers a listener to listen for state changes when a store calls Dispatch. GetState gets the state in the store. When the reducer was changed using action, we need to get the data in the new state. GetState is used in two places. One is that the Store needs to get the data in the state after submitting the action through Dispatch; the other is to use SUBSCRIBE to listen to the change of the state and call it to obtain new state data.

Having said that, the store’s core code is pretty short:

/** * reducer * @param {Object} state * @param {Function} reducer */
function createStore(reducer) {
  let state = null
  const listeners = []
  const subscribe = listener= > listeners.push(listener)
  const getState = (a)= > state
  const dispatch = action= > {
    // Overwrite the original object
    state = reducer(state, action)
    listeners.forEach(listener= > listener())
  }
  // Initialize state
  dispatch({})
  return {
    getState,
    dispatch,
    subscribe
  }
}
Copy the code

Reducer is a pure function that receives a state and action as parameters and returns a new state according to the action type. If no action type is matched, the default state is returned. Simple implementation is as follows:

function reducer(state, action) {
  if(! state) {return {
      title: {
        text: "water make redux".color: "red"
      },
      content: {
        text: "water make redux".color: "green"}}}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
  }
}
Copy the code

The action is simpler. It returns an object in which the Type attribute is required, as well as some other data. The following is an example:

/ generate storeconst store = createStore(reducer)
let oldState = store.getState()
// Listen for data changes to re-render the page
store.subscribe((a)= > {
  const newState = store.getState()
  renderApp(newState, oldState)
  oldState = newState
})
Render the page for the first time
renderApp(store.getState())
store.dispatch({
  type: "UPDATE_TITLE_TEXT".text: "water is fighting"
})
store.dispatch({
  type: "UPDATE_TITLE_COLOR".color: "#f00"
})
Copy the code

React-redux

React -redux encapsulates Redux and can be used directly in React. It also provides Provider and connect. A Provider is a component that accepts the Store as props and passes it down through the context so that any component in React can use the context to get the store. Connect is a function, as well as a high-level component (HOC), that returns a new component by passing in state and dispatch, written as follows:

connect(mapStateToProps, mapDispatchToProps, mergeProps, options)(component)
Copy the code

It can also be written as a decorator, which requires Babel support:

@connect(
	state,
	{ func }
)
Copy the code

For more details, see this project for a mini implementation: https://github.com/k-water/make-react-redux