This is the third day of my participation in the August More text Challenge. For details, see:August is more challenging

preface

This article is used as a summary of my study, and I will share it with you at the same time. It is suitable for the introduction of React Xiaowhite because of my limited personal technology. If you find any mistakes or questions, please point out or give directions! Thank you very much!

redux

A basic understanding

Learning document

  • Chinese documentation: www.redux.org.cn/
  • English documentation: redux.js.org/
  • GitHub: github.com/reduxjs/red…

redux

  1. Redux is a JAVASCRIPT library for managing state (not the React plugin library)
  2. It can be used in react, Angular, vue, etc., but it is mostly used in conjunction with React.
  3. Function: Centrally manages the state of multiple components in the React application.

When should I use redux

  1. The state of a component that needs to be readily available to other components (shared).
  2. One component needs to change the state of another (communication).
  3. General principle: don’t use it if you can, and consider using it if you don’t need it.

The working process

Redux’s three core concepts

action

  1. Object of action

  2. Contains two properties

    • Type: Identifies the attribute. The value is a string. It is unique and necessary
    • Data: Data attribute, value type arbitrary, optional attribute
  3. Code:

// This module is used to define the constant value of type type in the Action object. The purpose of this module is to make it easy to manage and prevent word miswriting
import {ADD_PERSON} from '.. /constant'
// Generate action objects specifically for components
export const addPerson = data= > ({type:ADD_PERSON,data})
Copy the code

reducer

  1. Used for initialization state and processing state.
  2. When processing, generate a pure function of the new state based on the old state and action.
const initState = xx
export default function xxxReducer(preState =initState, action) {
  const {type ,data} = action
  switch (type) {
    case JIA:
      return preState+1
    default :
      return preState
  }
}
Copy the code

store

  1. Objects that associate state, action, and Reducer together
  2. How do I get this object?
// Introduce createStore, which is designed to create the core Store object in Redux
import {createStore} from 'redux'
// Import the Reducer as the Count component service
import countReducer from './count_reducer'
//暴露store
export default createStore(countReducer)
Copy the code
  1. What does this object do?

    • getState(): getstate
    • dispatch(action)Distribute:actionTo triggerreducerCall to generate a newstate
    • subscribe(listener): Registers a listener when a new listener is generatedstateIs automatically invoked
componentDidMount(){
    // Check for state changes in redux and call render as soon as they happen
    store.subscribe(() = >{
            this.setState({})
    })
}
store.dispatch(createIncrementAction(value*1))
store.getState()
Copy the code

Redux core API

createStore

Function: Creates store objects that contain the specified Reducer

6.3.2 store object

  1. Function: The core managed object of the Redux library
  2. It maintains internally:
    1. state
    2. reducer
  3. Core method:
    1. getState()
    2. dispatch(action)
    3. subscribe(listener)
  4. Specific code:
    1. store.getState()
    2. store.dispatch({type:'INCREMENT', number})
    3. store.subscribe(render)

applyMiddleware()

Function: Redux-based middleware (plug-in library) for applications

combineReducers()

Function: Merges multiple Reducer functions

Redux asynchronous

1. By default, redux cannot be processed asynchronously.

2. Sometimes applications need to perform asynchronous tasks (Ajax, timer) in redux

Must download the plugin:

npm install --save redux-thunk

Import redux-thunk from ‘redux-thunk’ in store.js to support asynchronous action import thunk from ‘redux-thunk’

React-Redux

understand

  1. A dedicated React plugin
  2. Specifically to simplify the use of Redux in the React app

React-redux components fall into two broad categories

UI components

  • Only responsible for the rendering of the UI, without any business logic
  • Receiving data (general data and functions) via props
  • Does not use any of Redux’s apis
  • Generally saved in the Components folder

Container components

  • Responsible for managing data and business logic, not UI rendering
  • Use Redux’s API
  • It is usually saved in the containers folder

The relevant API

  1. Provider: Makes state data available to all components
import {Provider} from 'react-redux'
<Provider store={store}>
  <App/>
</Provider>
Copy the code
  1. Connect: Used to wrap UI components to generate container components
  2. MapStateToprops: Translates external data (the state object) into a label attribute of the UI component
  3. MapDispatchToProps: Converts a function that dispatches an action to a label attribute of a UI component
// Introduce the UI component for Count
import CountUI from '.. /.. /components/Count'
/ / into the action
import {
	createIncrementAction,
} from '.. /.. /redux/count_action'

// Introduce connect to connect UI components to redux
import {connect} from 'react-redux'

/* 1. MapStateToProps returns an object; MapStateToProps () props () props () props () props () props () props
function mapStateToProps(state){
	return {count:state}
}

/* 1. MapDispatchToProps returns an object; 3. MapDispatchToProps is a method used to pass the operation status */
function mapDispatchToProps(dispatch){
	return {
		jia:number= > dispatch(createIncrementAction(number))
	}
}

// Create and expose a Count container component using connect()()
export default connect(mapStateToProps,mapDispatchToProps)(CountUI)

/ / short
export default connect(
	state= > ({count:state}),
  {jia:createIncrementAction}
)(Count)
Copy the code

setState

  1. SetState (stateChange, [callback])—— Object setState

    2. Callback is an optional callback function that is called after the state has been updated and the interface has been updated (after the render call)Copy the code
  2. SetState (updater, [callback])—— setState of the function

    1. Updater is a function that returns the stateChange object. 2. The updater can receive the state and props. 3. Callback is an optional callback function that is not called until the status is updated and the interface is updated (after the render call).Copy the code

Conclusion:

  1. Object setState is short for functional setState (syntax sugar)
  2. Principles of use:
    • If the new state does not depend on the original state ===> Use object mode
    • If the new state depends on the original state ===> Use the function mode
    • If you need to get the latest state data after setState(), you read it in the second callback function
// Object setState
//1. Obtain the original count value
const {count} = this.state
//2. Update the status
this.setState({count:count+1},() = >{
  console.log(this.state.count);
})
//console.log(' line 12 output ',this.state.count); / / 0

// The setState function
this.setState( (state,props) = > ({count:state.count+1}),() = >{
  console.log(state.count)
})
Copy the code

LazyLoad Indicates lazy route loading

//1. Dynamically load the routing component using the React lazy function with the import() function ===> The routing component code is packaged separately
   const Login = lazy(() = >import('@/pages/Login'))
   
   // 3. Specify to show a custom loading interface before the routing package file is loaded through SuspenseSuspense Fallback can also package a general component in Suspense fallback={<h1>loading.....</h1>} ><Switch>
            <Route path="/xxx" component={Xxxx}/>
            <Redirect to="/login"/>
        </Switch>
    </Suspense>
Copy the code

Hooks

  1. What are React Hooks /Hooks?

    • Hook is a new feature/syntax added in React version 16.8.0
    • Allows you to use state and other React features in function components
  2. Three commonly used hooks

    • State Hook: React.useState()
    • Effect Hook: React.useEffect()
    • Ref Hook: React.useRef()
  3. State Hook

    • State Hook enables function components to have State State and read and write State data
    • Syntax: const [XXX, setXxx] = React. UseState (initValue)
    • Return value: an array of two elements, the first for the internal current state value, the second for the update state value function \
  4. SetXxx ()

    • SetXxx (newValue): takes a non-function value, specifies the new state value directly, and internally overwrites the original state value
    • SetXxx (value => newValue): a function that takes the original state value, returns the new state value, and internally overwrites the original state value
  5. Effect Hook

    • Effect Hooks allow you to perform side effects in function components (used to simulate lifecycle hooks in class components)
    • React side effects:
      • Send an Ajax request for data retrieval
      • Set the subscription/start timer
      • Manually change the real DOM
    • Syntax and instructions:
    useEffect(() = > { 
      // Any operation with side effects can be performed here
      return () = > { // Execute before component uninstallation
        // Do some finishing touches here, such as clearing the timer/unsubscribe, etc
      }
    }, [stateValue]) // If [] is specified, the callback will only be executed after the first render()
    Copy the code
    • UseEffect Hook can be viewed as a combination of the following three functions

      componentDidMount()

      componentDidUpdate()

      componentWillUnmount()

  6. Ref Hook

    • A Ref Hook can store/find a label or any other data in a function component
    • Syntax: const refContainer = useRef()
    • Function: Saves the label object. It does the same thing as react.createref ()
function Demo(){
	const [count,setCount] = React.useState(0)
	const myRef = React.useRef()

	React.useEffect(() = >{
		let timer = setInterval(() = >{
			setCount(count= > count+1)},1000)
		return () = >{
			clearInterval(timer)
		}
	},[])

	// add callback
	function add(){
		//setCount(count+1
		setCount(count= > count+1)}// Prompt for input callback
	function show(){
		alert(myRef.current.value)
	}

	// Uninstall the component callback
	function unmount(){
		ReactDOM.unmountComponentAtNode(document.getElementById('root'))}return (
		<div>
			<input type="text" ref={myRef}/>
			<h2>The current sum is: {count}</h2>
			<button onClick={add}>I + 1 point</button>
			<button onClick={unmount}>Uninstall the component</button>
			<button onClick={show}>Click on me to show the data</button>
		</div>)}Copy the code

Fragment

What it does: you no longer have to have a real DOM root tag

<Fragment key={1} >// Can participate in traversal
  <input type="text"/>
  <input type="text"/>< / fragments > or < ><input type="text"/>
  <input type="text"/>
</>
Copy the code

Context

A mode of communication between components, often used between ancestor components and descendant components

  1. Create a Context container object:

  const XxxContext = React.createContext()

  1. When rendering a subgroup, wrap xxxContext.Provider around it and pass data to the descendant component via the value property:


Subcomponent

  1. The descendant component reads data:

    Static contextType = xxxContext; static contextType = xxxContext; static contextType = xxxContext; </ xxxContext.consumer > </ xxxContext.consumer > </ xxxContext.consumer > </ xxxContext.consumer > </ xxxContext.consumer > </ xxxContext.consumer >Copy the code

Note: Context is not used in application development, it is usually encapsulated with the React plug-in

// Create the Context object
const MyContext = React.createContext()
const {Provider,Consumer} = MyContext
export default class A extends Component {

	state = {username:'tom'.age:18}
	render() {
		const {username,age} = this.state
		return (
			<div className="parent">
				<h3>This is component A</h3>
				<h4>My username is {username}</h4>
				<Provider value={{username,age}}>
					<B/>
				</Provider>
			</div>)}}class B extends Component {
	render() {
		return (
			<div className="child">
				<h3>This is component B</h3>
				<C/>
			</div>)}}Static contextType = MyContext Render () {const {username,age} = This. Context return (
      

)}} */

function C(){ return ( <div className="grand"> <h3>I am a C component</h3> <h4>The user name I received from component A:<Consumer>${value. Age} '} ${value.</Consumer> </h4> </div>)}Copy the code

Component optimization

Two problems with the project

  1. As long as setState() is executed, the component will re-render () even without changing the state data

  2. If only the current component is rerendered (), it will automatically rerender child components ==> inefficient

Efficient practices:

Rerender () only if the component’s state or props data has changed

The reason:

ShouldComponentUpdate () in a Component always returns true

Solution:

Method 1:

Override the shouldComponentUpdate() method to compare old and new state or props data, returning true if there are changes, and false if there are no changesCopy the code

Method 2:

PureComponent () {shouldComponentUpdate();} PureComponent () {shouldComponentUpdate();} This is just a shallow comparison between the state and props data. If only the data inside the data object has changed, return false. Do not modify the state data directly, but generate new data insteadCopy the code

PureComponent is commonly used in projects for optimization

import React, { PureComponent } from 'react'
export default class Parent extends PureComponent {
	state = {carName:"Mercedes c36".stus: ['zhang'.'xiao li'.'wang']}
	addStu = () = >{
		const {stus} = this.state
		this.setState({stus: ['liu'. stus]}) } changeCar =() = >{
		this.setState({carName:'Maybach'})}/* shouldComponentUpdate(nextProps,nextState){ // console.log(this.props,this.state); // console. Log (nextProps,nextState); // Props, target state return! this.state.carName === nextState.carName } */
	render() {
		console.log('Parent---render');
		const {carName} = this.state
		return (
			<div className="parent">
				<h3>I'm the Parent component</h3>
				{this.state.stus}&nbsp;
				<span>My carName is: {carName}</span><br/>
				<button onClick={this.changeCar}>Let me change</button>
				<button onClick={this.addStu}>Add a xiao Liu</button>
				<Child carName="Rolling"/>
			</div>)}}class Child extends PureComponent {
	/* shouldComponentUpdate(nextProps,nextState){ console.log(this.props,this.state); // Current props and state console.log(nextProps,nextState); // Props, target state return! this.props.carName === nextProps.carName } */
	render() {
		console.log('Child---render');
		return (
			<div className="child">
				<h3>I'm the Child component</h3>
				<span>I got this: {this.props. CarName}</span>
			</div>)}}Copy the code

\

render props

How do I dynamically pass structures (tags) with content into a component?

The Vue:

The React of:

- Use the child props: pass the structure through the component tag body. - Use the render props: pass the structure through the component tag propertyCopy the code

children props

  <A>
    <B>xxxx</B>
  </A>
  {this.props.children}
Copy the code

Problem: If component B needs data from component A, it cannot do so

render props

  <A render={(data) => <C data={data}></C>}></A>

{this.props. Render (internal state data)}

{this.props. Data}}

Error boundary

To understand:

Error bounds: Used to catch descendant component errors and render alternate pages

Features:

You can only catch errors generated during the life cycle of descendant components. You cannot catch errors generated by your own components and errors generated by other components in composite events and timers

Usage:

GetDerivedStateFromError cooperate componentDidCatch// Life cycle function, which is triggered if the background component reports an error
// getDerivedStateFromError is called with an error message when a child of Parent reports an error
static getDerivedStateFromError(error){
  console.log('@ @ @',error);
  return {hasError:error}
}

componentDidCatch(){
  console.log('Here the error is counted and reported to the server to notify the coders of bug resolution.');
}
Copy the code