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