This article is excerpted from the Fire Wolf 1 Deity

React development tips: 34 Things to Know

preface

React is one of the top three front-end frameworks and a skill in development; Here are some tips on how to develop Vue with React:

The source address

Please poke, welcome star

rendering

1 Component Communication

1.1 props

Child components

import React from "react";
import PropTypes from "prop-types";
import { Button } from "antd";

export default class EightteenChildOne extends React.Component {
  static propTypes = { //propTypes verifies incoming types, as detailed in Tip 11
    name: PropTypes.string
  };

  click = () = > {
    // Pass the child to the parent through the trigger method
    this.props.eightteenChildOneToFather("This is props changing the value of the parent element");
  };

  render() {
    return (
      <div>
        <div>This is the value passed in as props {this.props. Name}</div>
        <Button type="primary" onClick={this.click}>Click to change the parent element value</Button>
      </div>); }}Copy the code

The parent component

<EightteenChildOne name={'Name value passed to props'} eightteenChildOneToFather={(mode) = >this.eightteenChildOneToFather(mode)}></EightteenChildOne> 

/ / or
<EightteenChildOne name={'propsThe incomingnameValue '}eightteenChildOneToFather={this.eightteenChildOneToFather.bind(this)}></EightteenChildOne>
Copy the code

Props passes multiple values: traditional

const {dataOne,dataTwo,dataThree} = this.state
<Com dataOne={dataOne} dataTwo={dataTwo} dataThree={dataThree}>
Copy the code

Upgrade the writing

<Com {... {dataOne,dataTwo,dataThree}}>Copy the code

1.2 Props upgrade

This method is an example of how to use the props method to change the value of the parent component

Call the parent component method to change the value

/ / the parent component
state = {
  count: {}
}
changeParentState = obj= > {
    this.setState(obj);
}
/ / child component
onClick = () = > {
    this.props.changeParentState({ count: 2 });
}
Copy the code

1.3 Provider, Consumer, and Context

Context before 16.x is defined as a global object, similar to vue eventBus. If the component wants to use this value, it is directly retrieved from this. Context

/ / the root component
class MessageList extends React.Component {
  getChildContext() {
    return {color: "purple".text: "item text"};
  }

  render() {
    const {messages} = this.props || {}
    const children = messages && messages.map((message) = >
      <Message text={message.text} />
    );
    return <div>{children}</div>;
  }
}

MessageList.childContextTypes = {
  color: React.PropTypes.string
  text: React.PropTypes.string
};

// Intermediate components
class Message extends React.Component {
  render() {
    return (
      <div>
        <MessageItem />
        <Button>Delete</Button>
      </div>); }}// The receiver component
class MessageItem extends React.Component {
  render() {
    return (
      <div>
        {this.context.text}
      </div>
    );
  }
}

MessageItem.contextTypes = {
  text: React.PropTypes.string //React.PropTypes was deprecated in version 15.5, see the actual React version of the project
};

class Button extends React.Component {
  render() {
    return (
      <button style={{background: this.context.color}} >
        {this.props.children}
      </button>
    );
  }
}

Button.contextTypes = {
  color: React.PropTypes.string
}
Copy the code

The Context after 2.16.x uses the Provider and Customer patterns, passing a value in the top-level Provider, fetching the value in the descendant Consumer, and passing functions. Use to modify context to declare a global context definition,context.js

import React from 'react'
let { Consumer, Provider } = React.createContext();// Create the context and expose the Consumer and Provider modes
export {
    Consumer,
    Provider
}
Copy the code

Parent component import

/ / import the Provider
import {Provider} from ".. /.. /utils/context"

<Provider value={name}>
  <div style={{border:'1px solid red',width:'30% ',margin:'50px auto',textAlign:'center'}} >
    <p>Values defined by the parent component :{name}</p>
    <EightteenChildTwo></EightteenChildTwo>
  </div>
</Provider>
Copy the code

Child components

/ / import Consumer
import { Consumer } from ".. /.. /utils/context"
function Son(props) {
  return (
    // The Consumer container can get the name attribute passed above and display the corresponding value
    <Consumer>
      {name => (
        <div
          style={{
            border: "1px solid blue",
            width: "60% ",margin: "20px auto",
            textAlign: "center}} ">// In Consumer, you can get the value of the parent component directly by name<p>The child component. Get the value of the parent component :{name}</p>
        </div>
      )}
    </Consumer>
  );
}
export default Son;
Copy the code

1.4 EventEmitter

The EventEmiter portal uses the Events plug-in to define a global event mechanism

1.5 Route Parameter Transmission

1.params

<Route path='/path/:name' component={Path}/>
<link to="/path/2">xxx</Link>
this.props.history.push({pathname:"/path/"+ name}); Read parameters with:this.props.match.params.name
Copy the code

2.query

<Route path='/query' component={Query}/>
<Link to={{ pathname : '/query',query : { name : 'sunny' }}}>this.props.history.push({pathname:"/query",query: { name : 'sunny' }}); Read parameters with: this props. Location. Query. NameCopy the code

3.state

<Route path='/sort ' component={Sort}/>
<Link to={{ pathname : '/sort',state : { name : 'sunny' }}}>this.props.history.push({pathname:"/sort ",state : { name : 'sunny' }}); Read parameters with: this props. Location. Query. The stateCopy the code

4.search

<Route path='/web/search ' component={Search}/>
<link to="web/search? id=12121212">xxx</Link>
this.props.history.push({pathname:`/web/search? id${row.id}`}); Read parameters with:this.props.location.search
Copy the code

There is a bug in react-router-dom: v4.2.2. The parameter redirect page will be blank and will be loaded after refreshing

5. The advantages and disadvantages

Params refresh page parameters are not lost in HashRouter and BrowserRouter routes. 2. State refresh page parameters are not lost in BrowserRouter and HashRouter routes. 4. Query and state can pass objectsCopy the code

1.6 onRef

The mechanism of onRef communication is to pass this(component instance) as a parameter to the parent component through the event mechanism of props, and the parent component can operate the state and methods of the child component

EightteenChildFour.jsx

export default class EightteenChildFour extends React.Component {
  state={
      name:'This is the name value of the component EightteenChildFour'
  }

  componentDidMount(){
    this.props.onRef(this)
    console.log(this) // -> pass EightteenChildFour to the parent this.props. OnRef () method
  }

  click = () = > {
    this.setState({name:'This is the component click method that changes the name value EightteenChildFour.'})};render() {
    return (
      <div>
        <div>{this.state.name}</div>
        <Button type="primary" onClick={this.click}>Click to change the name value of the component EightteenChildFour</Button>
      </div>); }}Copy the code

eighteen.jsx

<EightteenChildFour onRef={this.eightteenChildFourRef}></EightteenChildFour>

eightteenChildFourRef = (ref) = >{
  console.log(The Ref value of eightteenChildFour is)
  // The ref contains the entire component instance
  console.log(ref)
  // Invoke child component methods
  ref.click()
}
Copy the code

1.7 ref

React obtains the entire subcomponent instance from the ref attribute

EightteenChildFive.jsx

// Common component definition methods
export default class EightteenChildFive extends React.Component {
  state={
      name:'This is the name value of the component EightteenChildFive'
  }

  click = () = > {
    this.setState({name:'This is the component click method that changes the name value EightteenChildFive.'})};render() {
    return (
      <div>
        <div>{this.state.name}</div>
        <Button type="primary" onClick={this.click}>Click to change the name value of the component EightteenChildFive</Button>
      </div>); }}Copy the code

eighteen.jsx

// The hook gets the instance
componentDidMount(){
    console.log(The Ref value of eightteenChildFive is)
      // The ref contains the entire component instance, as well as the child component instance
    console.log(this.refs["eightteenChildFiveRef"])}// The component defines the ref attribute
<EightteenChildFive ref="eightteenChildFiveRef"></EightteenChildFive>
Copy the code

1.8 redux

Redux is a standalone event communication plugin, which will not be described here. Please stamp portal:

1.9 MobX

MobX is also a standalone event communication plugin, so I won’t go into too much detail here.

1.10 flux

Flux is also a standalone event communication plugin, so I won’t go into too much detail here.

1.11 hooks

1. Hooks are using userReducer and context to implement communication, and the following simulation implements a simple REdux 2. Core files are divided into Action, Reducer,types action.js

import * as Types from './types';

export const onChangeCount = count= > ({
    type: Types.EXAMPLE_TEST,
    count: count + 1
})
Copy the code

reducer.js

import * as Types from "./types";
export const defaultState = {
  count: 0
};
export default (state, action) => {
  switch (action.type) {
    case Types.EXAMPLE_TEST:
      return {
        ...state,
        count: action.count
      };
    default: {
      returnstate; }}}Copy the code

types.js

export const EXAMPLE_TEST = 'EXAMPLE_TEST';
Copy the code

eightteen.jsx

export const ExampleContext = React.createContext(null);// Create the createContext context

// Define the component
function ReducerCom() {
  const [exampleState, exampleDispatch] = useReducer(example, defaultState);

  return (
    <ExampleContext.Provider
      value={{ exampleState.dispatch: exampleDispatch }}
    >
      <EightteenChildThree></EightteenChildThree>
    </ExampleContext.Provider>
  );
}
Copy the code

EightteenChildThree JSX / / component

import React, {  useEffect, useContext } from 'react';
import {Button} from 'antd'

import {onChangeCount} from '.. /.. /pages/TwoTen/store/action';
import { ExampleContext } from '.. /.. /pages/TwoTen/eighteen';

const Example = () = > {

    const exampleContext = useContext(ExampleContext);

    useEffect(() = > { // Listen for changes
        console.log('Change executed')
    }, [exampleContext.exampleState.count]);

    return (
        <div>
            <p>Value is {exampleContext. ExampleState. Count}</p>
            <Button onClick={()= >ExampleContext. Dispatch (onChangeCount (exampleContext. ExampleState. Count))} > click add 1</Button>
        </div>)}export default Example;
Copy the code

React-hooks: react-hooks: react-hooks: react-hooks: react-hooks: react-hooks

4. The hooks are:

The hook, role
useState Initialize and set state
useEffect ComponentDidMount, componentDidUpdate and componentWillUnmount, so you can listen for useState definition changes
useContext Define a global object, like context
useReducer Functions can be enhanced to provide redux-like functionality
useCallback The first parameter is an anonymous function, which is the body of the function we want to create. The second argument is an array of variables that determine whether the function body needs to be recreated. If the value of the variable passed in remains unchanged, the result of the memory is returned. If any of these items change, a new result is returned
useMemo UseCallback returns a function, and useDemo returns a value
useRef Gets the DOM corresponding to the ref attribute
useImperativeMethods Customize the instance value exposed to the parent component when using ref
useMutationEffect It works the same as useEffect, but synchronizes the same phase of React’s DOM changes before updating its sibling
useLayoutEffect The useEffect is the same, but fires synchronously after all DOM changes

5.useImperativeMethods

function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeMethods(ref, () = > ({
    focus: () = >{ inputRef.current.focus(); }}));return <input ref={inputRef} . />;
}
FancyInput = forwardRef(FancyInput);
Copy the code

1.12 slot.

Slot refers to passing labels from a parent component to a child component, similar to the V-slot scenario of VUE: some components share some DOM logic, and some of it is independent

// Parent component file
import SlotChild from 'SlotChild'

<SlotChild
slot={<div>This is the slot of the parent component</div>}>
</SlotChild>

/ / child componentChild component directlythis.props. Slot gets the contentCopy the code

1.13 contrast

methods advantages disadvantages
props No external plug-ins need to be introduced Sibling component communication needs to establish a common parent component, trouble
Props upgrade There is no need to import external plug-ins, child to parent, no need to receive methods in the parent component With the props
The Provider, the Consumer and the Context No need to introduce external plug-ins, communication across multiple levels of components or sibling components State data state tracking trouble
EventEmitter Can support brother, father and son component communication External plug-ins are introduced
Routing and the cords Can support sibling component transfer value, page simple data transfer is very convenient The parent and child components cannot communicate
onRef You can get the entire sub-component instance in a simple way Brother component communication trouble, official do not recommend using
ref With onRef With onRef
redux Established a global state manager, brother and father communication can be solved External plug-ins were introduced
mobx Established a global state manager, brother and father communication can be solved External plug-ins were introduced
flux Established a global state manager, brother and father communication can be solved External plug-ins were introduced
hooks 16. X new property to support communication between sibling and parent components You need to use it with context
slot Supports label transfer from parent to child

Redux, Mobx and Flux comparison

methods introduce
redux 1. Core modules :Action,Reducer,Store; 2. Store and change logic are separate; 3. Only one Store; 4. Single Store with reducer; 5. No concept of scheduler; 6. Container components are related; 7. The state is immutable; 8. More functional programming
mobx 1. Core modules: Action, Reducer, Derivation; 2. There are multiple stores. 3. Design is more oriented towards object-oriented programming and responsive programming, usually wrapping state as observable objects, which can be updated automatically once the state objects change
flux 1. Core modules: Store, ReduceStore, Container; 2. There are multiple stores.

2.require.context()

This is the WebPack API, which was introduced in vue Tips. Since both vue and React projects are packaged based on WebPack, it can be used in React as well

const path = require('path')
const files = require.context('@/components/home'.false./.vue$/)
const modules = {}
files.keys().forEach(key= > {
  const name = path.basename(key, '.vue')
  modules[name] = files(key).default || files(key)
})
Copy the code

3.Decorator

Definition: Decorators are a new feature in ES7 that allows you to modify class attributes

import React from 'react'
import Test from '.. /.. /utils/decorators'

@Test
// As long as the Decorator is followed by Class, Class is already passed implicitly into the Decorator by default.
class TwentyNine extends React.Component{
    componentDidMount(){
        console.log(this.'decorator.js') // This is an instance of the class
        console.log(this.testable)
    }
    render(){
        return (
            <div>This is trick 23</div>)}}export default TwentyNine
Copy the code

decorators.js

function testable(target) {
  console.log(target)
  target.isTestable = true;
  target.prototype.getDate = () = >{
    console.log( new Date()}}export default testable
Copy the code

Many middleware, such as Redux, encapsulate the use of decorators

4. Use the if… else

Scenario: Sometimes you need to display different content based on different status values

import React from "react";

export default class Four extends React.Component {
  state = {
    count: 1
  };
  render() {
    let info
    if(this.state.count===0){
      info=(
        <span>This is the quantity shown as 0</span>)}else if(this.state.count===1){
      info=(
        <span>This is the quantity shown as 1</span>)}return (
      <div>
        {info}
      </div>); }}Copy the code

5. Five ways to change the state value

Method 1

let {count} = this.state
this.setState({count:2})
Copy the code

Method 2: callBack

this.setState(({count}) = >({count:count+2}))
Copy the code

Method 3: Accept the state and props parameters

this.setState((state, props) = > {
    return { count: state.count + props.step };
});
Copy the code

Pattern 4: hooks

const [count, setCount] = useState(0)
/ / set the value
setCount(count+2)
Copy the code

Method 5: Call after the state value changes

this.setState(
    {count:3},() = >{
        // Get a result and do something})Copy the code

6. Monitor states changes

Use componentWillReceiveProps before 1.16 x

componentWillReceiveProps (nextProps){
  if(this.props.visible ! == nextProps.visible){//props changes what to do}}Copy the code

Note: in some cases componentWillReceiveProps also triggers in props value did not change, because for the first time in the life cycle of will not be called after the render, but could be invoked in each render after = when the parent component again send props

After 2.16 x use getDerivedStateFromProps, 16. After x componentWillReveiveProps also not remove

export default class Six extends React.Component {
  state = {
    countOne:1.changeFlag:' '
  };
  clickOne(){
    let {countOne} = this.state
    this.setState({countOne:countOne+1})};static getDerivedStateFromProps (nextProps){
    console.log('Change execution')
    return{
      changeFlag:'State value change execution'}}render() {
    const {countOne,changeFlag} = this.state
    return (
      <div>
        <div>
         <Button type="primary" onClick={this.clickOne.bind(this)}>Click on add 1</Button><span>CountOne value is {countOne}</span>
        <div>{changeFlag}</div>
        </div>
      </div>); }}Copy the code

7. Component definition method

Mode 1:ES5 Function definition

function FunCom(props){
  return <div>This is the component defined by Function</div>
}
ReactDOM.render(<FunCom name="Sebastian" />, mountNode)

Before hooks came out, this was the way to define stateless components. Now hooks can handle state, too
Copy the code

Mode 2: ES5 createClass definition

const CreateClassCom = React.createClass({
  render: function() {
  return <div>This is the component defined by React. CreateClass</div>}})Copy the code

Method 3: extends of ES6

class Com extends React.Component {
  render(){
    return(<div>This is the component defined by React.Com Ponent</div>)}}Copy the code

call

export default class Seven extends React.Component {
  render() {
    return (
      <div>
        <FunCom></FunCom>
        <Com></Com>
      </div>); }}Copy the code

Difference: the ES5 createClass is to use the function simulation class write to es6; Component created by es6 new class properties This component is easy to create.

8. Get component from the ref property

Method 1: Also the earliest use, this. Refs can also be applied to components to retrieve component instances

class RefOne extends React.Component{
  componentDidMount() {
    this.refs['box'].innerHTML='This is div box, get it by ref'
  }
  render(){
    return(
      <div ref="box"></div>)}}Copy the code

Method 2: the callback function mounts the function on the DOM node or component. The input parameter of the function is the DOM node or component instance. The effect is the same as the string form, which is to obtain its reference

class RefTwo extends React.Component{
  componentDidMount() {
    this.input.value='This is the input field default.';
    this.input.focus();
  }
  render(){
    return(
      <input ref={comp= >{ this.input = comp; }} / >)}}Copy the code

CreateRef () After React 16.3, use this method to create a ref. Assign it to a variable, mount it to a DOM node or component using ref’s current property, and get an instance of the DOM node or component

class RefThree extends React.Component{
  constructor(props){
    super(props);
    this.myRef=React.createRef();
  }
  componentDidMount(){
    console.log(this.myRef.current);
  }
  render(){
    return <input ref={this.myRef}/>}}Copy the code

Method 4:React. ForwardRef React 16.3 is available later and can be used to create child components that pass refs

class RefFour extends React.Component{
  constructor(props){
    super(props);
    this.myFourRef=React.forwardRef();
  }
  componentDidMount(){
    console.log(this.myFourRef.current);
  }
  render(){
    return <Child ref={this.myFourRef}/>}}Copy the code

Subcomponents are created with the React. ForwardRef and can pass refs to internal nodes or components for cross-level references. The forwardRef gets an instance of the original component in the higher – order component. This feature is highlighted in Tip 18

9. The static use

Scenario: Declare keywords for static methods, which can be called even without component instances

export default class Nine extends React.Component {
  static update(data) {
    console.log('Static method call executed')}render() {
    return (
      <div>This is the static keyword skill</div>
    );
  }
}

Nine.update('2')
Copy the code

Static creates a property or method that belongs to the class. Static creates a property or method that belongs to the class. Component is an instance of this class. Component props and state belong to this instance, so the instance has not been created yet. So the static and not react to define, and combined with the static keyword, said this method will not be instance inheritance, but directly through the class to call, so also is unable to access to this 4. GetDerivedStateFromProps also by static method to monitor value, see skills 6

10. The constructor and super

Review: 1. Before we talk about these two properties, let’s review the ES6 function definition method 2. By default, every class defined in class has a constructor function, which is the main function of the constructor. The this inside the function body points to the generated instance. The super keyword is used to access and call functions on the parent object of an object

export default class Ten extends React.Component {
  constructor() { // The main function of class
    super(a)/ / React.Com ponent. Prototype. Constructor. Call (this), is to get the properties and methods of the parent
    this.state = {
      arr: []}}render() {
    return (
      <div>This is tip 10</div>); }}Copy the code

11.PropTypes

Scenario: Checking the data types of incoming subcomponents Type checking PropTypes Deprecated since React V15.5, use prop-types mode 1: old

class PropTypeOne extends React.Component {
  render() {
    return (
      <div>
        <div>{this.props.email}</div>
        <div>{this.props.name}</div>
      </div>
    );
  }
}

PropTypeOne.propTypes = {
  name: PropTypes.string, / / value for array, bool, func, number, object, symbol
  email: function(props, propName, componentName) { // Custom verification
    if(!/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/.test(
        props[propName]
      )
    ) {
      return new Error(
        "Component" + componentName + "Attributes in." + propName + "Does not fit the mailbox format"); }}},Copy the code

Method 2: Use the static attribute keyword of ES7

class PropTypeTwo extends React.Component {
  static propTypes = {
      name:PropTypes.string
  };
  render() {
    return (
      <div>
        <div>{this.props.name}</div>
      </div>); }}Copy the code

12. Use class field declaration syntax

Scenario: You can initialize local state without using constructors and declare class methods by using arrow functions without additional binding to them

class Counter extends Component {
  state = { value: 0 };

  handleIncrement = () = > {
    this.setState(prevState= > ({
      value: prevState.value + 1
    }));
  };

  handleDecrement = () = > {
    this.setState(prevState= > ({
      value: prevState.value - 1
    }));
  };

  render() {
    return (
      <div>
        {this.state.value}

        <button onClick={this.handleIncrement}>+</button>
        <button onClick={this.handleDecrement}>-</button>
      </div>)}}Copy the code

13. Asynchronous components

1. Scenario: Route switchover. If routes on multiple pages are loaded synchronously, the process is slow

2. Core API: loader: a component that needs to be loaded Loading: a page display component that is not loaded Delay: loading time timeout: timeout time

Install syntax-dynamic-import. React-loadable is implemented via webpack asynchronous import

const Loading = () = > {
  return <div>loading</div>;
};

const LoadableComponent = Loadable({
  loader: () = > import(".. /.. /components/TwoTen/thirteen"),
  loading: Loading
});

export default class Thirteen extends React.Component {
  render() {
    return <LoadableComponent></LoadableComponent>; }}Copy the code

4. Loadable.map () loads high-level components of multiple resources in parallel

14. Dynamic components

Scenario: Doing a TAB switch involves dynamic component loading, which is essentially using a ternary expression to determine whether the component is displayed

class FourteenChildOne extends React.Component {
    render() {
        return <div>This is dynamic component 1</div>; }}class FourteenChildTwo extends React.Component {
    render() {
        return <div>This is dynamic component 2</div>; }}export default class Fourteen extends React.Component {
  state={
      oneShowFlag:true
  }
  tab=() = >{
      this.setState({oneShowFlag:!this.state.oneShowFlag})
  }
  render() {
    const {oneShowFlag} = this.state
    return (<div>
        <Button type="primary" onClick={this.tab}>Display component {oneShowFlag? 2:1}</Button>
        {oneShowFlag?<FourteenChildOne></FourteenChildOne>:<FourteenChildTwo></FourteenChildTwo>}
    </div>); }}Copy the code

Whether the display can be short-circuited if it is a single component

oneShowFlag&&<FourteenChildOne></FourteenChildOne>
Copy the code

15. Recursive components

Scenario: The Tree component uses a react. Fragment or div wrapped loop

class Item extends React.Component {
  render() {
    const list = this.props.children || [];
    return (
      <div className="item">
        {list.map((item, index) => {
          return (
            <React.Fragment key={index}>
              <h3>{item.name}</h3>
              {// 当该节点还有children时,则递归调用本身
              item.children && item.children.length ? (
                <Item>{item.children}</Item>
              ) : null}
            </React.Fragment>
          );
        })}
      </div>); }}Copy the code

16. Controlled and uncontrolled components

Controlled components: The state of a component is controlled by the React state value, state, or props

class Controll extends React.Component {
  constructor() {
    super(a);this.state = { value: "This is the controlled component default" };
  }
  render() {
    return <div>{this.state.value}</div>; }}Copy the code

Uncontrolled components: Components are not controlled by React state values, but by dom properties or React refs

class NoControll extends React.Component {
  render() {
    return <div>{this.props.value}</div>; }}Copy the code

Import code:

export default class Sixteen extends React.Component {
  componentDidMount() {
    console.log("The uncontrolled component value obtained by ref is.this.refs["noControll"]);
  }
  render() {
    return (
      <div>
        <Controll></Controll>
        <NoControll
          value={"This is an incoming value for an uncontrolled component "}ref="noControll"
        ></NoControll>
      </div>); }}Copy the code

17. High-level Component (HOC)

17.1 define

1. A higher-order function-like definition that takes a component as an argument or returns a component; 2. Function: Extract repetitive code to realize component reuse, common scenarios, page reuse; Conditional rendering, rendering logic for control components (render hijacking), common scenes, permission control; Capture/hijack the life cycle of the component being processed, common scenarios, component rendering performance tracking, logging

17.2 Implementation method

1. Property proxy

import React,{Component} from 'react';

const Seventeen = WrappedComponent= >
  class extends React.Component {
    render() {
      constprops = { ... this.props,name: "This is a higher-order component."
      };
      return <WrappedComponent {. props} / >; }};class WrappedComponent extends React.Component {
  state={
     baseName:'This is the base component' 
  }
  render() {
    const {baseName} = this.state
    const {name} = this.props
    return <div>
        <div>Base component value {baseName}</div>
        <div>The value obtained by the higher-order component property broker is {name}</div>
    </div>}}export default Seventeen(WrappedComponent)
Copy the code

2. The principle of reverse inheritance is to use super to change the this direction of the reorganized component, and then some values of the container component can be processed in that component

  const Seventeen = (WrappedComponent) = >{
    return class extends WrappedComponent {
        componentDidMount() {
            this.setState({baseName:'This is the base component name modified by reverse inheritance'})}render(){
            return super.render(); }}}class WrappedComponent extends React.Component {
  state={
     baseName:'This is the base component' 
  }
  render() {
    const {baseName} = this.state
    return <div>
        <div>Base component value {baseName}</div>
    </div>}}export default Seventeen(WrappedComponent);
Copy the code

18. Whether the element is displayed

Ternary expressions are commonly used

 flag?<div>According to the content</div>:' '
 flag&&<div>According to the content</div>
Copy the code

Dialog component creation

Dialog should be the most used component. There are three different ways to create a Dialog: 1. State controls whether the component is displayed or not

 class NineteenChildOne extends React.Component {
  render() {
    const Dialog = () = > <div>This is shell one</div>;

    return this.props.dialogOneFlag && <Dialog />; }}Copy the code

Method 2: through ReactDom. Render to create outer layer – mount the root node Through the primary the createElement method, the appendChild, RemoveChild and react ReactDOM. Render, ReactDOM unmountComponentAtNode to control elements of the show and hide

NineteenChild.jsx

import ReactDOM from "react-dom";

class Dialog {
  constructor(name) {
    this.div = document.createElement("div");
    this.div.style.width = "200px";
    this.div.style.height = "200px";
    this.div.style.backgroundColor = "green";
    this.div.style.position = "absolute";
    this.div.style.top = "200px";
    this.div.style.left = "400px";
    this.div.id = "dialog-box";
  }
  show(children) {
    / / destroy
    const dom = document.querySelector("#dialog-box");
    if(! dom){// Multiple clicks are compatible
      / / show
      document.body.appendChild(this.div);
      ReactDOM.render(children, this.div); }}destroy() {
    / / destroy
    const dom = document.querySelector("#dialog-box");
    if(dom){// Multiple clicks are compatible
      ReactDOM.unmountComponentAtNode(this.div); dom.parentNode.removeChild(dom); }}}export default {
  show: function(children) {
    new Dialog().show(children);
  },
  hide: function() {
    newDialog().destroy(); }};Copy the code

nineteen.jsx

twoSubmit=() = >{
    Dialog.show('This is shell two'.)
  }

  twoCancel=() = >{
    Dialog.hide()
  }
Copy the code

20.React.memo

What it does: Use pureComponent or shouldComponentUpdate to avoid component rendering when the input properties of a class component are the same. Now, you can do the same by wrapping function components in react.Memo

import React from "react";

function areEqual(prevProps, nextProps) {
  /*
  如果把 nextProps 传入 render 方法的返回结果与
  将 prevProps 传入 render 方法的返回结果一致则返回 true,
  否则返回 false
  */
  if (prevProps.val === nextProps.val) {
    return true;
  } else {
    return false; }}// react.memo () takes two arguments, the first is a pure function and the second is a comparison function
export default React.memo(function twentyChild(props) {
  console.log("MemoSon rendered : " + Date.now());
  return <div>{props.val}</div>;
}, areEqual);
Copy the code

21.React.PureComponent

React.PureComponent defines a component class. ShouldComponentUpdate (); the react.pureComponent implements shouldComponentUpdate() via a shallow comparison of props and state. 3.React.PureComponent applies to classes, while react. memo applies to functions. 4. If the props and state of the component are the same, and the content of the render is the same, then you can use the React.PureComponent to improve the performance of the component

class TwentyOneChild extends React.PureComponent{  // The component directly inherits react. PureComponent
  render() {
    return <div>{this.props.name}</div>}}export default class TwentyOne extends React.Component{
    render(){
        return (
            <div>
              <TwentyOneChild name={'this isReact.PureComponent'}></TwentyOneChild>
            </div>)}}Copy the code

22.React.Component

Function: it is based on the ES6 class React components, the React allows you to define a class or function as components, then define a component class, needs to inherit React.Com ponent

export default class TwentyTwo extends React.Component{ // Component defines methods
    render(){
        return (
            <div>This is trick number two</div>)}}Copy the code

23. Print falsy value in JSX

Definition: 1. A falsy value (virtual value) is a value assumed to be false in a Boolean context; 2. The value is 0, “”,” ‘, ` `, null, and undefined, NaN

export default class TwentyThree extends React.Component{
    state={myVariable:null}
    render(){
        return (
            <div>{String(this.state.myVariable)}</div>)}}Copy the code

Virtual values are implicitly converted to false if displayed directly, so the page is not displayed

24.ReactDOM.createPortal

What it does: The component’s Render function returns elements that are mounted on its parent component, and createPortal provides an excellent solution for rendering child nodes to DOM nodes that exist outside the parent component

import React from "react";
import ReactDOM from "react-dom";
import {Button} from "antd"

const modalRoot = document.body;

class Modal extends React.Component {
  constructor(props) {
    super(props);
    this.el = document.createElement("div");
    this.el.style.width = "200px";
    this.el.style.height = "200px";
    this.el.style.backgroundColor = "green";
    this.el.style.position = "absolute";
    this.el.style.top = "200px";
    this.el.style.left = "400px";
  }

  componentDidMount() {
    modalRoot.appendChild(this.el);
  }

  componentWillUnmount() {
    modalRoot.removeChild(this.el);
  }

  render() {
    return ReactDOM.createPortal(this.props.children, this.el); }}function Child() {
  return (
    <div className="modal">This is the content created via reactdom.createPortal</div>
  );
}

export default class TwentyFour extends React.Component {
  constructor(props) {
    super(props);
    this.state = { clicks: 0 };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState= > ({
      clicks: prevState.clicks + 1
    }));
  }

  render() {
    return (
      <div>
          <Button onClick={this.handleClick}>Click on add 1</Button>
        <p>{this.state. Clicks}</p>
        <Modal>
          <Child />
        </Modal>
      </div>); }}Copy the code

The element is appended to the specified element

25. Use innerHTML in React

Scenario: Some background returns are HTML formatted fields, so you need the innerHTML attribute

export default class TwentyFive extends React.Component {
  render() {
    return (
      <div dangerouslySetInnerHTML={{ __html: "<span>This is the rendered HTML content</span>}} "></div>); }}Copy the code

26.React.createElement

Syntax: React. CreateElement (type, [props], […children])

Source:

export default class TwentySix extends React.Component {
  render() {
    return (
      <div>{React.createElement( "div", { id: "one", className: "two" }, React.createElement("span", { id: "SpanOne"}, "this is the first span tag "), react. createElement("br"), react. createElement("span", {id: "SpanTwo"}, "this is the second SPAN tag "))}</div>); }}Copy the code

JSX dom is essentially converted to js with react. createElement

/ / JSX syntax
<div id='one' class='two'>
    <span id="spanOne">this is spanOne</span>
    <span id="spanTwo">this is spanTwo</span>
</div>

// Convert to js
React.createElement(
  "div",
 { id: "one".class: "two" },
 React.createElement( "span", { id: "spanOne" }, "this is spanOne"), 
 React.createElement("span", { id: "spanTwo" }, "this is spanTwo"))Copy the code

27.React.cloneElement

Grammar:

React.cloneElement(
  element,
  [props],
  [...children]
)
Copy the code

Function: This method copies the component, passes values to the component, or adds property core code

React.Children.map(children, child= > {
  return React.cloneElement(child, {
    count: _this.state.count
  });
})
Copy the code

28.React.Fragment

What it does :React.Fragment lets you aggregate a list of child elements without adding extra node core code to the DOM

render() {
    const { info } = this.state;
    return (
      <div>
        {info.map((item, index) => {
          return (
            <React.Fragment key={index}>
              <div>{item.name}</div>
              <div>{item.age}</div>
            </React.Fragment>
          );
        })}
      </div>
    );
  }
Copy the code

29. Loop elements

Instead of encapsulating instructions like V-for in VUE, they are traversed by map

{arr.map((item,index) = >{
  return(
    <div key={item.id}>
      <span>{item.name}</span>
      <span>{item.age}</span>
    </div>)})}Copy the code

30. Set and get custom properties for DOM

What it does: Some pass values through custom attributes

export default class Thirty extends React.Component {
  click = e= > {
    console.log(e.target.getAttribute("data-row"));
  };

  render() {
    return (
      <div>
        <div data-row={"Attribute1"} data-col={"Attribute2"} onClick={this.click}>Click get properties</div>
      </div>); }}Copy the code

31. Bind events

Scenario: Interaction involves event clicking, and then clicking on selected values to pass parameters is also a common scenario

import React from "react";
import { Button } from 'antd'

export default class Three extends React.Component {
  state = {
    flag: true.flagOne: 1
  };
  click(data1,data2){
    console.log('data1 value is',data1)
    console.log('data2 value is',data2)
  }
  render() {
    return (
      <div>
        <Button type="primary" onClick={this.click.bind(this,Parameters'1', 'parameters2')} >Click on the event</Button>
      </div>); }}Copy the code

The usage method is detailed in the source code routes.js

32.React-Router

32.1 Differences between V3 and V4

1. Earlier versions of V3 or V separate router and layout Components; 2.V4 is a centralized router, which realizes Layout and page nesting through Route nesting. Layout and Page components are part of the router. V3 routing is exclusive, which means that only one route is obtained. 4. Routes in V4 are inclusive by default, which means multiple routes. You can match and render at the same time. If you want to match only one route, you can use Switch. In Switch, only one route will be rendered. You can also add exact to each route

32.2 the use of

import { HashRouter as Router, Switch  } from "react-router-dom";

class App extends React.Component{
    render(){
        const authPath = '/login' // By default, the page is returned when you are not logged in
        let authed = this.props.state.authed || localStorage.getItem('authed') // You can use redux to change this value after logging in
        return (
            <Router>
                <Switch>
                    {renderRoutes(routes, authed, authPath)}
                </Switch>
            </Router>)}}Copy the code

V4 is through Route nesting, realize Layout and page nesting,Switch Switch Route function

33. Style introduction method

Mode 1:import Import

import './App.css';
Copy the code

Mode 2: Inline mode

import React from 'react';

const Header = () = > {

    const heading = 'Header component'

    return(
        <div style={{backgroundColor:'orange'}} >
            <h1>{heading}</h1>
        </div>)} orimport React from 'react';

const footerStyle = {
    width: '100%'.backgroundColor: 'green'.padding: '50px'.font: '30px'.color: 'white'.fontWeight: 'bold'
}

export const Footer = () = > {
    return(
        <div style={footerStyle}>At the bottom of the component</div>)}Copy the code

34. Dynamically bind className

Principle: Control className values by ternary expressions

render(){
  const flag=true
  return (
    <div className={flag?"active":"no-active"} >This is trick 34</div>)}Copy the code

conclusion

Here are 34 React tips from actual project development; Source code address, please stamp welcome star