34 tips that React development must know [nearly 1W words]

Posted by satya61229 on Wed, 13 Nov 2019 03:12:26 +0100

Preface

React is one of the three front-end frameworks and a skill in interview and development.
This paper summarizes some skills and techniques of React development from the actual development, which are suitable for students who are new to React or have some project experience.
Long text in thousands of words, recommended collection.
Sequential articles: 36 tips for Vue development

Source Address

Stamp , welcome star

Design sketch

1. Whether the element is displayed

General Ternary Expression

 flag?<div>show contents</div>:''

2. Circular Elements

Instead of encapsulating instructions like v-for inside a vue, it traverses through a map

3. Binding events

Scenario: Interaction involves an event click, and then clicking on a selected value to pass on 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,'Parameter 1','Parameter 2')}>Click Event</Button>
      </div>
    );
  }
}

4. Use if...else

Scenario: Sometimes different content needs to be displayed according to different status value pages

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 a quantity zero display</span>
      )
    } else if(this.state.count===1){
      info=(
        <span>This is Quantity 1 display</span>
      )
    }
    return (
      <div>
        {info}
      </div>
    );
  }
}

5. Four ways to change the state value

Mode 1

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

Mode 2:callBack

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

Mode 3: Receive state and props parameters

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

Mode 4:hooks

const [count, setCount] = useState(0)
// Set Value
setCount(count+2)

6. Listen for changes in states

Use componentWillReveiveProps before 1.16.x

componentWillReceiveProps (nextProps){
  if(this.props.visible !== nextProps.visible){
      //What props value changes to do
  }
}

Note: Sometimes componentWillReceiveProps will also be triggered if the props value does not change because they will not be called after the first render in the life cycle, but will be called every subsequent render = when the parent component passes props again

GetDerivedStateFromProps was used after 2.16.x and componentWillReveiveProps was not removed after 16.x

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 Plus 1</Button><span>countOne Value is{countOne}</span>
        <div>{changeFlag}</div>
        </div>
      </div>
    );
  }
}

7. Component Definition Method

Function Definition in Mode 1:ES5

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

// Before hooks came out, this was the way to define stateless components, and now with hooks you can handle States

Mode 2: createClass definition for ES5

const CreateClassCom = React.createClass({
  render: function() {
  return <div>This is React.createClass Defined Components</div>
  }
});

Extensions in Mode 3:ES6

class Com extends React.Component {
  render(){
    return(<div>This is React.Component Defined Components</div>)
  }
}

call

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

Difference: ES5's createClass is an es6 that uses function s to simulate the writing of class es;

 Component created by the properties of the new class in es6 This component is easy to create.

8. Get component from ref attribute

Mode 1: It's also the earliest use, obtained by this.refs [attribute name]
You can also work on components to get an instance of the component

class RefOne extends React.Component{
  componentDidMount() {
    this.refs['box'].innerHTML='This is div Box,adopt ref Obtain'
  }
  render(){
    return(
      <div ref="box"></div>
    )
  }
}

Mode 2: Callback function, which mounts the function on the dom node or component. The function takes in a dom node or component instance and achieves the same effect as a string, which is to get its reference

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

Mode 3:React.createRef()
Use this method to create refs after React 16.3.Assign it to a variable and mount it on the dom node or component by Ref. The ref's current property gives you 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}/>
  }
}

Mode 4:React.forwardRef
Provided after React 16.3, can be used to create subcomponents to pass ref s

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

Subcomponents are created by React.forwardRef, which allows refs to be passed to internal nodes or components, thereby enabling cross-level references.ForForward ref provides an example of the original component in advanced components. This feature is highlighted in Tip 18.

9.static use

Scenario: A keyword that declares a static method that can be called directly even without a component instance

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

Nine.update('2')

Be careful:
1.ES6 class, we usually define a class when we define a component, while static creates a property or method that belongs to this class
2. The component is an instance of this class, and the props and state s of the component belong to this instance, so the instance has not been created
3. Static is not defined by react, but by adding the static keyword, it means that the method will not be inherited by the instance, but will be invoked directly through the class, so it is also inaccessible to this
4.getDerivedStateFromProps also listens for values through static methods, see Tip 6 for details

10.constructor and super

Review:
1. Before discussing these two properties, review the ES6 function definition method
2. Each class defined as a class has a constructor function by default, which is the primary function of the constructor, with this inside the function pointing to the generated instance
3. 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() { // Main function of class
    super() // React.Component.prototype.constructor.call(this) actually takes the properties and methods of the parent class
    this.state = {
      arr:[]
    }
  }  
  render() {
    return (
      <div>
        //This is Tip 10
      </div>
    );
  }
}

11.PropTypes

Scenario: Detect data types of incoming subcomponents
Type checking PropTypes have been deprecated since React v15.5. Use prop-types
Mode 1: Old Writing

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

PropTypeOne.propTypes = {
  name: PropTypes.string, //Values can be array,bool,func,number,object,symbol
  email: function(props, propName, componentName) { //Custom Check
    if (
      !/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/.test(
        props[propName]
      )
    ) {
      return new Error(
        "assembly" + componentName + "Properties in" + propName + "Does not conform to mailbox format"
      );
    }
  },
};

Method 2: Utilize static attribute keyword of ES7

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

12. Use class fields to declare syntax

Scenario: Local states can be initialized without using constructors and class methods can be declared using arrow functions without additional binding

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>
    )
  }
}

13. Asynchronous Components

1. Scenario: Routing switch, slow if multiple page routes are loaded simultaneously

2. Core API:
loader: Components that need to be loaded
loading: Unloaded page display component
delay:Delayed Load Time
timeout:Timeout

3. Usage:
Install react-loadable, Babel plugin install syntax-dynamic-import. react-loadable is implemented through asynchronous import of webpack

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>;
  }
}

4.Loadable.Map()
High-order components that load multiple resources in parallel

14. Dynamic Components

Scenario: Making a tab switch involves component dynamic loading
Essentially, a ternary expression is used to determine whether a component is displayed

class FourteenChildOne extends React.Component {
    render() {
        return <div>This is a dynamic graph</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 Components{oneShowFlag?2:1}</Button>
        {oneShowFlag?<FourteenChildOne></FourteenChildOne>:<FourteenChildTwo></FourteenChildTwo>}
    </div>);
  }
}

15. Recursive Components

Scenario: tree component
Use React.Fragment or div package loops

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>
              {// When the node also has a child, the recursive call itself
              item.children && item.children.length ? (
                <Item>{item.children}</Item>
              ) : null}
            </React.Fragment>
          );
        })}
      </div>
    );
  }
}

16. Controlled and uncontrolled components

Controlled Components: Components have their own state

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

Uncontrolled Components: Components have no state of their own, and values are controlled by ref or props in the parent component

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

Import code:

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

17. Advanced Components

17.1 Definition

Is the definition of a higher-order function that takes a component as a parameter or returns a component

17.2 Implementation Method

1. Attribute Agent

import React,{Component} from 'react';

const Seventeen = WraooedComponent =>
  class extends React.Component {
    render() {
      const props = {
        ...this.props,
        name: "This is a high-order component"
      };
      return <WrappedComponent {...props} />;
    }
  };

class WrappedComponent extends React.Component {
  state={
     baseName:'This is the underlying component' 
  }
  render() {
    const {baseName} = this.state
    const {name} = this.props
    return <div>
        <div>Base component value is{baseName}</div>
        <div>The value obtained from the higher-order component property agent is{name}</div>
    </div>
  }
}

export default Seventeen(WrappedComponent)

2. Reverse Inheritance
The principle is to use super to change the this direction of a component, which can then handle some values of a container component

  const Seventeen = (WrappedComponent)=>{
    return class extends WrappedComponent {
        componentDidMount() {
            this.setState({baseName:'This is the modified base component name through reverse inheritance'})
        }
        render(){
            return super.render();
        }
    }
}

class WrappedComponent extends React.Component {
  state={
     baseName:'This is the underlying component' 
  }
  render() {
    const {baseName} = this.state
    return <div>
        <div>Base component value is{baseName}</div>
    </div>
  }
}

export default Seventeen(WrappedComponent);

18 Component Communication

18.1 props

Subcomponents

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

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

  click = () => {
    // Child heir by triggering method
    this.props.eightteenChildOneToFather("This is props Change the value of the parent element");
  };

  render() {
    return (
      <div>
        <div>This is through props Incoming value{this.props.name}</div>
        <Button type="primary" onClick={this.click}>
          //Click to change parent element value
        </Button>
      </div>
    );
  }
}

Parent Component

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

When props pass multiple values:
Traditional Writing

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

Upgrade Writing

<Com {...{dataOne,dataTwo,dataThree}}>

18.2 props upgrade

Principle: Pros is used within a child component to get the parent component method called directly, thereby changing the value of the parent component
Note: This method is similar to props in that it is an application of props, so there are no examples in the source code

Call parent component method to change the value

// Parent Component
state = {
  count: {}
}
changeParentState = obj => {
    this.setState(obj);
}
// Subcomponents
onClick = () => {
    this.props.changeParentState({ count: 2 });
}

18.3 Provider,Consumer, and Context

1.Context is defined as a global object before 16.x, similar to vue's eventBus, if the component wants to use this value it gets directly through this.context

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

  render() {
    const children = this.props.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>
    );
  }
}

//Sun Component (Receiving Component)
class MessageItem extends React.Component {
  render() {
    return (
      <div>
        {this.context.text}
      </div>
    );
  }
}

MessageItem.contextTypes = {
  text: React.PropTypes.string //React.PropTypes were discarded at version 15.5 to 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
};

Contexts after 2.16.x use Provider and Customer modes, pass in a value in the top-level Provider, get that value in the children's Consumer s, and pass functions to modify the context
Declare a global context definition, context.js

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

Parent Component Import

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

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

Subcomponents

// Import Consumer
import { Consumer } from "../../utils/context"
function Son(props) {
  return (
    //The Consumer container, which takes the name attribute passed down above and displays 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>Subcomponents.Get the value of the parent component:{name}</p>
        </div>
      )}
    </Consumer>
  );
}
export default Son;

18.4 EventEmitter

EventEmiter Portal
Define a global event mechanism using the events plug-in

18.5 Routing Passwords

1.params

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

2.query

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

3.state

<Route path='/sort ' component={Sort}/>
<Link to={{ path : '/sort ' , state : { name : 'sunny' }}}> 
this.props.history.push({pathname:"/sort ",state : { name : 'sunny' }});
//Read parameters using: this.props.location.query.state 

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 using: this.props.location.search

5. Advantages and disadvantages

1.params and search can only pass strings, refresh page parameters will not be lost
 2.query and state can pass objects, but refreshing page parameters will be lost

18.6 onRef

Principle: The onRef communication principle is that this (component instance) of a component is passed as a parameter to the parent component through the props event mechanism, and the parent component can operate on the state and method of the child component

EightteenChildFour.jsx

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

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

  click = () => {
    this.setState({name:'This is a component click Method Change EightteenChildFour Changing name value'})
  };

  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>
    );
  }
}

eighteen.jsx

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

eightteenChildFourRef = (ref)=>{
  console.log('eightteenChildFour Of Ref Value is')
  // Get ref that includes the entire component instance
  console.log(ref)
  // Call subcomponent methods
  ref.click()
}

18.7 ref

Principle: It is to get the entire sub-component instance through the ref property of React and then operate on it

EightteenChildFive.jsx

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

  click = () => {
    this.setState({name:'This is a component click Method Change EightteenChildFive Changing name value'})
  };

  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>
    );
  }
}

eighteen.jsx

// Hook Get Instance
componentDidMount(){
    console.log('eightteenChildFive Of Ref Value is')
      // The retrieved ref includes the entire component instance, and the subcomponent instance can also be retrieved
    console.log(this.refs["eightteenChildFiveRef"])
  }

// Component Definition ref Properties
<EightteenChildFive ref="eightteenChildFiveRef"></EightteenChildFive>

18.8 redux

redux is a stand-alone event communication plug-in that is not described much here
Port: https://www.redux.org.cn/docs...

18.9 mbox

mobox is also a stand-alone event communication plugin, which is not described much here
https://cn.mobx.js.org/

18.10 flux

mobox is also a stand-alone event communication plugin, which is not described much here
https://facebook.github.io/fl...

18.11 hooks

1.hooks use userReducer and context to communicate. The following simulation implements a simple redux
2. The core file is divided into action,reducer,types
action.js

import * as Types from './types';

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

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: {
      return state;
    }
  }
};

types.js

export const EXAMPLE_TEST = 'EXAMPLE_TEST';

eightteen.jsx

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

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

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

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 implemented')
    }, [exampleContext.exampleState.count]);

    return (
        <div>
            <p>Value is{exampleContext.exampleState.count}</p>
            <Button onClick={() => exampleContext.dispatch(onChangeCount(exampleContext.exampleState.count))}>Click Plus 1</Button>
        </div>
    )
}

export default Example;

3. The hooks actually encapsulate the API of the original React to expose the hooks that are more convenient to use.

4. The hooks are:

Hook Name Effect
useState Initialization and Setup Status
useEffect componentDidMount, componentDidUpdate, and componentWillUnmount and the combination, so you can listen for changes in useState definition values
useContext Define a global object, similar to context
useReducer Can enhance function to provide Redux-like functionality
useCallback Memory has two parameters. The first parameter is an anonymous function, which is the body we want to create.The second parameter is an array, each of which is used to determine whether a variable in the function body needs to be recreated, and returns the result of memory if the value of the incoming variable remains unchanged.If any changes are made, a new result is returned
useMemo The effect and incoming parameters are consistent with useCallback, useCallback returns the function, and useDemo returns the value
useRef Get dom corresponding to ref attribute
useImperativeMethods Customize instance values exposed to parent components when using ref
useMutationEffect It works the same as useEffect, but it triggers synchronization at the same stage that React performs its DOM changes before updating a sibling component
useLayoutEffect Same as useEffect, but triggered 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);

More hooks intro stamps

18.12 Contrast

Method Advantage shortcoming
props External plug-ins are not required Brother component communication requires common parent components, troublesome
props upgrade No external plug-ins need to be introduced, no child parent, no method receipt in the parent component Same props
Provider,Consumer, and Context No need to introduce external plug-ins to communicate across multilevel or sibling components Status data status tracking hassle
EventEmitter Supports sibling, parent-child component communication To introduce external plug-ins
Routing parameters Can support brotherly component value transfer, simple data transfer page is very convenient Parent-child component communication is powerless
onRef You can get an entire sub-component instance, which is easy to use Brothers'components have trouble communicating and are not officially recommended
ref Same as onRef Same as onRef
redux A global state manager has been set up to allow brothers, fathers and sons to communicate External plug-ins introduced
mobx A global state manager has been set up to allow brothers, fathers and sons to communicate External plug-ins introduced
flux A global state manager has been set up to allow brothers, fathers and sons to communicate External plug-ins introduced
hooks 16.x New property to support sibling, parent-child component communication Need to be used with context

Comparison of redux, mobx and flux

Method introduce
redux 1. Core modules: Action,Reducer,Store;2. Store and change logic are separate; 3. There is only one Store;4. Single Store with hierarchical reducer; 5. There is no concept of scheduler; 6. Container components are connected; 7. State is not changeable; 8. More is to follow the idea of functional programming.
mobx 1. Core modules: Action,Reducer,Derivation;2. Multiple stores; 3. Design more towards object-oriented programming and responsive programming, usually wrapping states as observable objects, which can be updated automatically when state objects change
flux 1. Core modules: Store,ReduceStore,Container;2. Multiple stores;

19.Dialog Component Creation

Dialog should be a more versatile component, there are three different ways to create it
Mode 1: Control whether the component is displayed through a state

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

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

Mode 2: Create a bullet layer through ReactDom.render - mount the root node outer layer
Control the display and hiding of elements through native createElement,appendChild, removeChild, and react RectDOM.render, ReactDOM.unmountComponentAtNode

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){ //Compatible with multiple clicks
      // display
      document.body.appendChild(this.div);
      ReactDOM.render(children, this.div);
    }
  }
  destroy() {
    // Destroy
    const dom = document.querySelector("#dialog-box");
    if(dom){//Compatible with multiple clicks
      ReactDOM.unmountComponentAtNode(this.div);
      dom.parentNode.removeChild(dom);
    }
  }
}
export default {
  show: function(children) {
    new Dialog().show(children);
  },
  hide: function() {
    new Dialog().destroy();
  }
};

nineteen.jsx

twoSubmit=()=>{
    Dialog.show('This is Layer 2')
  }

  twoCancel=()=>{
    Dialog.hide()
  }

20.React.memo

Role: When class components have the same input properties, pureComponent or shouldComponentUpdate can be used to avoid rendering of components.Now you can do the same by wrapping function components in React.memo

import React from "react";

function areEqual(prevProps, nextProps) {
  /*
  If nextProps is passed into render method, the result will be
  If the result of passing prevProps into render method is consistent, it returns true.
  Otherwise return false
  */
  if (prevProps.val === nextProps.val) {
    return true;
  } else {
    return false;
  }
}

// React.memo() has two parameters, 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);

21.React.PureComponent

Effect:
1.React.PureComponent is similar to React.Component in that it defines a component class.
2. The difference is that React.Component does not implement shouldComponentUpdate(), while React.PureComponent does through a shallow comparison of props and state s.
3.React.PureComponent acts on classes, while React.memo acts on functions.
4. If the props and state s of the component are the same and the contents of the render are the same, then React.PureComponent can be used to improve the performance of the component

class TwentyOneChild extends React.PureComponent{  //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 is React.PureComponent How to use it'}></TwentyOneChild>
            </div>
        )
    }
}

22.React.Component

Role: A React component based on the ES6 class, React allows you to define a class or function as a component, so if you define a component class, you need to inherit React.Component

export default class TwentyTwo extends React.Component{ //Component Definition Method
    render(){
        return (
            <div>This is Tip 22</div>
        )
    }
}

23. Print falsy values in JSX

Definition:
1. The false value (imaginary value) is the value identified as false in the Boolean context;
2. Values are 0,'','', ``, null, undefined, NaN

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

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

24.ReactDOM.createPortal

Role: The elements returned by the render function of a component 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 through 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 Plus 1</Button>
        <p>Number of clicks: {this.state.clicks}</p>
        <Modal>
          <Child />
        </Modal>
      </div>
    );
  }
}

This appends the element to the specified element

25. Use innerHTML in React

Scenario: Some background returns are html formatted fields, so the innerHTML attribute is required

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

Why is this a dangerous property because it can lead to XSS attacks
_html is two

26.React.createElement

Grammar:
React.createElement(
type,
[props],
[...children]
)

Source code:

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 Label"),
          React.createElement("br"),
          React.createElement("span", { id: "spanTwo" }, "This is the second span Label")
        )}
      </div>
    );
  }
}

Principle: Essentially, all DOMS of JSX that are ultimately converted to js are React.createElement s

// 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")
);

27.React.cloneElement

Grammar:

React.cloneElement(
  element,
  [props],
  [...children]
)

Role: This method copies components, passes values to components, or adds properties
Core Code

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

28.React.Fragment

Role: React.Fragment allows you to aggregate a list of child elements without adding extra nodes to the DOM
Core Code

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>
    );
  }

29.Decorator

Definition: decorator is a new feature of ES7 that can modify class properties

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

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

export default TwentyNine

decorators.js

function testable(target) {
  console.log(target)
  target.isTestable = true;
  target.prototype.getDate = ()=>{
    console.log( new Date() )
  }
}

export default testable

Many middleware, like redux, encapsulate the use of Decorator

https://www.jianshu.com/p/275...

30. Set and get custom properties for DOM

Role: 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={"Attribute 1"} data-col={"Attribute 2"} onClick={this.click}>
          //Click to get properties
        </div>
      </div>
    );
  }
}

31.require.context()

This is the api for webpack, which is described in the Vue tips, because both Vue and React projects are packaged based on webpack, so they can also be used in react

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)
})

Usage method is used in detail in source routes.js

32.React-Router

Differences between 32.1 V3 and V4

1.V3 or earlier versions of V separated router from layout components;
2.V4 is a centralized router. Layout and page are nested by Route nesting. Layout and page components are part of the router
3. The routing rule in V 3 is exclusive, meaning that only one route is eventually obtained
routes in 4.V 4 are inclusive by default, which means that multiple <routes>can be matched and rendered at the same time. If you only want to match one route, you can use Switch. Only one <Route>in <Switch>will be rendered, and exact can be added to each route to achieve a precise match.
Redirect, browser redirection, match when many don't match

32.2 Use

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

class App extends React.Component{
    render(){
        const authPath = '/login' // Pages returned by default when not logged in can be set by yourself
        let authed = this.props.state.authed || localStorage.getItem('authed') // If you can use redux to modify this value after logging in
        return (
            <Router>
                <Switch>
                    {renderRoutes(routes, authed, authPath)}
                </Switch>
            </Router>
        )
    }
}

V4 is nested by Route, Layout and page, Switch switches the role of routing

33. Style introduction methods

Mode 1:import import

import './App.css';

Mode 2: Inline mode

import React from 'react';

const Header = () => {

    const heading = 'Header Component'

    return(
        <div style={{backgroundColor:'orange'}}>
            <h1>{heading}</h1>
        </div>
    )
}

//perhaps
import React from 'react';

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

export const Footer = () => {
    return(
        <div style={footerStyle}>
            //Bottom Component
        </div>
    )
}

34. Dynamic binding className

Principle: Control the className value through a ternary expression

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

summary

This is React's 34 tips summarized from actual project development.
The original code word is not easy, welcome star;
Source address, Stamp , welcome star

Topics: Javascript React Attribute Vue Fragment