preface
React is one of the three front-end frameworks and is also a skill in development;
This paper summarizes some skills of React development from the actual development, which is suitable for students who are beginners of React or have some project experience
Source code address
(1) component communication
1.1 props
Subassemblies
import React from "react"; import PropTypes from "prop-types"; import { Button } from "antd"; export default class EightteenChildOne extends React.Component { static propTypes = { //propTypes verifies the incoming type. For details, please refer to skill 11 name: PropTypes.string }; click = () => { // Pass child to parent by triggering method this.props.eightteenChildOneToFather("This is props Change the value of the parent element"); }; render() { return ( <div> <div>This is through props Value passed in{this.props.name}</div> <Button type="primary" onClick={this.click}> Click to change the parent element value </Button> </div> ); } } Copy code
Parent component
<EightteenChildOne name={'props Incoming name value'} eightteenChildOneToFather={(mode)=>this.eightteenChildOneToFather(mode)}></EightteenChildOne> // perhaps <EightteenChildOne name={'props Incoming name value'} eightteenChildOneToFather={this.eightteenChildOneToFather.bind(this)}></EightteenChildOne> Copy code
When props transfers multiple values:
Traditional writing
const {dataOne,dataTwo,dataThree} = this.state <Com dataOne={dataOne} dataTwo={dataTwo} dataThree={dataThree}> Copy code
Upgrade writing
<Com {...{dataOne,dataTwo,dataThree}}> Copy code
1.2 props upgrade
Principle: in the sub component, the method of the parent component is directly called by props to change the value of the parent component
Note: this method is almost the same as props, which is the application of props, so there is no example in the source code
Call the parent component method to change the value
// Parent component state = { count: {} } changeParentState = obj => { this.setState(obj); } // Subassemblies onClick = () => { this.props.changeParentState({ count: 2 }); } Copy code
1.3 Provider,Consumer and Context
1. Before 16.x, context defines a global object, similar to vue's eventBus. If the component wants to use this value, it can be directly obtained through this.context
//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 component class Message extends React.Component { render() { return ( <div> <MessageItem /> <Button>Delete</Button> </div> ); } } //Sub component (receiving component) class MessageItem extends React.Component { render() { return ( <div> {this.context.text} </div> ); } } MessageItem.contextTypes = { text: React.PropTypes.string //React.PropTypes was abandoned 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 code
The context after 2.16.x uses the Provider and Customer modes, passing in the value in the top-level Provider, obtaining the value in the descendant level Consumer, and passing the function to modify the context to declare a global context definition. context.js
import React from 'react' let { Consumer, Provider } = React.createContext();//Create context and expose the Consumer and Provider modes export { Consumer, Provider } Copy code
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> Copy code
Subassemblies
// Import Consumer import { Consumer } from "../../utils/context" function Son(props) { return ( //The Consumer container can get the name attribute passed down 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 directly get the value of the parent component through name <p>Sub assembly. Get the value of the parent component:{name}</p> </div> )} </Consumer> ); } export default Son; Copy code
1.4 EventEmitter
EventEmitter portal Use 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}); For reading parameters:this.props.match.params.name Copy code
2.query
<Route path='/query' component={Query}/> <Link to={{ pathname : '/query' , query : { name : 'sunny' }}}> this.props.history.push({pathname:"/query",query: { name : 'sunny' }}); For reading parameters: this.props.location.query.name Copy code
3.state
<Route path='/sort ' component={Sort}/> <Link to={{ pathname : '/sort ' , state : { name : 'sunny' }}}> this.props.history.push({pathname:"/sort ",state : { name : 'sunny' }}); For reading parameters: this.props.location.query.state Copy 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}`}); For reading parameters: this.props.location.search Copy code
There is a bug in react router DOM: v4.2.2. The parameter transfer jump page will be blank and will be loaded after refreshing
5. Advantages and disadvantages
1.params stay HashRouter and BrowserRouter The refresh page parameters in the route will not be lost 2.state stay BrowserRouter The refresh page parameter will not be lost in HashRouter The refresh page will be lost in the route 3.query: stay HashRouter and BrowserRouter The refresh page parameters in the route will be lost 4.query and state Can transfer objects Copy code
1.6 onRef
Principle: onRef communication principle is to pass this (component instance) of the component as a parameter to the parent component through the event mechanism of props, and the parent component can operate 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 Altered name value'}) }; render() { return ( <div> <div>{this.state.name}</div> <Button type="primary" onClick={this.click}> Click change component EightteenChildFour of name value </Button> </div> ); } } Copy code
eighteen.jsx
<EightteenChildFour onRef={this.eightteenChildFourRef}></EightteenChildFour> eightteenChildFourRef = (ref)=>{ console.log('eightteenChildFour of Ref Value is') // The obtained ref includes the entire component instance console.log(ref) // Call subcomponent method ref.click() } Copy code
1.7 ref
Principle: get the whole sub component instance through the ref attribute of React, and then operate
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 Altered name value'}) }; render() { return ( <div> <div>{this.state.name}</div> <Button type="primary" onClick={this.click}> Click change component EightteenChildFive of name value </Button> </div> ); } } Copy code
eighteen.jsx
// Hook get instance componentDidMount(){ console.log('eightteenChildFive of Ref Value is') // The obtained ref includes the entire component instance, and the sub component instance can also be obtained console.log(this.refs["eightteenChildFiveRef"]) } // Component definition ref attribute <EightteenChildFive ref="eightteenChildFiveRef"></EightteenChildFive> Copy code
1.8 redux
redux is an independent event communication plug-in, so I will not describe it here Please stamp the portal:
1.9 MobX
MobX is also an independent event communication plug-in, which will not be described here
Please stamp the portal:
1.10 flux
flux is also an independent event communication plug-in, so I will not describe it here
Please stamp the portal:
1.11 hooks
1.hooks uses userReducer and context to realize communication. The following is a simple redux simulation
2. Core files are divided into action, reducer and types
action.js
import * as Types from './types'; export const onChangeCount = count => ({ type: Types.EXAMPLE_TEST, count: count + 1 }) Copy 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: { return state; } } }; Copy code
types.js
export const EXAMPLE_TEST = 'EXAMPLE_TEST'; Copy code
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> ); } Copy 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(() => { // Monitoring changes console.log('The change has been implemented') }, [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 code
3.hooks actually encapsulates the original React API and exposes hooks that are convenient to use;
4. Hooks include:
Hook name | effect |
---|---|
useState | Initialization and setting status |
useEffect | componentDidMount, componentDidUpdate and componentWillUnmount are combined, so you can listen for changes in the value defined by useState |
useContext | Define a global object, similar to context |
useReducer | Functions can be enhanced to provide Redux like functions |
useCallback | The memory function has two parameters. The first parameter is an anonymous function, which is the function body we want to create. The second parameter is an array. Each item in the array is used to determine whether the function body needs to be recreated. If the value of the passed variable remains unchanged, the memory result is returned. If any item is changed, a new result is returned |
useMemo | The action and the passed in parameters are consistent with useCallback, which returns the function and useDemo returns the value |
useRef | Get the dom corresponding to the ref attribute |
useImperativeMethods | Customize the instance value exposed to the parent component when ref is used |
useMutationEffect | The function is the same as useEffect, but before updating the sibling component, it is triggered synchronously at the same stage when React performs its DOM change |
useLayoutEffect | The function is the same as useEffect, but it is 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); Copy code
1.12 slot
Slot is to transfer the label of the parent component to the child component, similar to the v-slot of vue
Scenario: some components only share some dom logic, some of which are independent
// Parent component file import SlotChild from 'SlotChild' <SlotChild slot={<div>This is the parent component's slot</div>}> </SlotChild> // Subassemblies Direct acquisition of sub components this.props.slot The content can be obtained Copy code
1.13 comparison
method | advantage | shortcoming |
---|---|---|
props | No need to introduce external plug-ins | Brother component communication needs to establish a common parent component, which is troublesome |
props upgrade | There is no need to introduce external plug-ins, and the child is passed to the parent. There is no need to receive in the parent component with methods | Same as props |
Provider,Consumer and Context | There is no need to introduce external plug-ins, which is a communication tool across multi-level components or brother components | Status data: status tracking is troublesome |
EventEmitter | Can support brother, parent-child component communication | To import an external plug-in: |
Route parameters | It can support brother components to transfer values. The page is simple and the data transfer is very convenient | Communication between parent and child components is powerless |
onRef | You can obtain the entire sub component instance, which is simple to use | Brother component communication is troublesome, and it is not recommended to use officially |
ref | Same as onRef | Same as onRef |
redux | A global state manager has been established, and brother parent-child communication can be solved | Introduced external plug-ins |
mobx | A global state manager has been established, and brother parent-child communication can be solved | Introduced external plug-ins |
flux | A global state manager has been established, and brother parent-child communication can be solved | Introduced external plug-ins |
hooks | 16.x new content, can support brother, parent-child component communication | It needs to be used together with context |
slot | Support parent to child label transfer |
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 layered reducer; 5. There is no concept of scheduler; 6. The container components are connected; 7. The status cannot be changed; 8. More importantly, it follows the idea of functional programming |
mobx | 1. Core modules: Action,Reducer,Derivation;2. There are multiple stores; 3. The design is more oriented towards object-oriented programming and responsive programming. Usually, the state is wrapped into observable objects. Once the state object changes, it can be automatically updated |
flux | 1. Core modules: Store,ReduceStore,Container;2. There are multiple stores; |
2.require.context()
This is the webpack api, which is introduced in Vue skills. Because Vue and react projects are packaged based on webpack, 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) }) Copy code
3.Decorator
Definition: decorator is a new feature of ES7, which can modify the properties of a class
import React from 'react' import Test from '../../utils/decorators' @Test //As long as the Decorator is followed by Class, by default, Class has been passed into the Decorator as a parameter. class TwentyNine extends React.Component{ componentDidMount(){ console.log(this,'decorator.js') // this here is an instance of a class console.log(this.testable) } render(){ return ( <div>This is skill 23</div> ) } } export default TwentyNine Copy code
decorators.js
function testable(target) { console.log(target) target.isTestable = true; target.prototype.getDate = ()=>{ console.log( new Date() ) } } export default testable Copy code
Many middleware, such as redux, encapsulates the use of Decorator
4. Use if... else
Scenario: sometimes different contents need 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 of 0 displayed</span> ) } else if(this.state.count===1){ info=( <span>This is a quantity of 1 displayed</span> ) } return ( <div> {info} </div> ); } } Copy code
5. Five ways to change the state value
Mode 1
let {count} = this.state this.setState({count:2}) Copy code
Mode 2:callBack
this.setState(({count})=>({count:count+2})) Copy code
Mode 3: receive state and props parameters
this.setState((state, props) => { return { count: state.count + props.step }; }); Copy code
Mode 4:hooks
const [count, setCount] = useState(0) // Set value setCount(count+2) Copy code
Mode 5: called after the state value is changed
this.setState( {count:3},()=>{ //Get the result do something } ) Copy code
6. Listen for changes in states
Use componentWillReceiveProps before 1.16.x
componentWillReceiveProps (nextProps){ if(this.props.visible !== nextProps.visible){ //props value changes what you do } } Copy code
Note: sometimes componentWillReceiveProps will be triggered even if the props value does not change, because it will not be called after the first render in the life cycle, but will be called in each subsequent render = when the parent component transmits props again
Getderivedstatefromprops is used after 2.16.x, and componentWillReveiveProps is 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 add 1</Button><span>countOne Value is{countOne}</span> <div>{changeFlag}</div> </div> </div> ); } } Copy code
7. Component definition method
Method 1: Function definition of 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 method to define stateless components. Now hooks can also handle states Copy code
Method 2: createClass definition of Es5
const CreateClassCom = React.createClass({ render: function() { return <div>This is React.createClass Defined components</div> } }); Copy code
Mode 3: Extensions of ES6
class Com extends React.Component { render(){ return(<div>This is React.Component Defined components</div>) } } Copy code
call
export default class Seven extends React.Component { render() { return ( <div> <FunCom></FunCom> <Com></Com> </div> ); } } Copy code
Difference: the createClass of ES5 is created by using the function to simulate the class writing method of es6; The component created by adding the attribute of class in es6 is simple to create
8. Get component through ref attribute
Mode 1: also the earliest usage, through this Refs [property name acquisition] can also be applied to the component to obtain the component instance
class RefOne extends React.Component{ componentDidMount() { this.refs['box'].innerHTML='This is div Box,adopt ref obtain' } render(){ return( <div ref="box"></div> ) } } Copy code
Mode 2: callback function. Mount 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 that of the string form, and the reference is obtained
class RefTwo extends React.Component{ componentDidMount() { this.input.value='This is the default value of the input box'; this.input.focus(); } render(){ return( <input ref={comp => { this.input = comp; }}/> ) } } Copy code
Mode 3: react Createref() after react version 16.3, use this method to create Ref. Assign it to a variable and mount it on the dom node or component through Ref. the current attribute of the ref will get the 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 code
Method 4:React.forwardRef
Provided after React 16.3, it can be used to create subcomponents to pass ref
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 code
The subcomponents pass through react forwardRef can be passed to internal nodes or components to realize cross level reference. forwardRef can obtain the instance of the original component in the high-level component This function will be emphasized in skill 18
9.static use
Scenario: a keyword that declares a static method. A static method means that it can be called directly even if there is no component instance
export default class Nine extends React.Component { static update(data) { console.log('The static method call is executed') } render() { return ( <div> This is static Keyword skills </div> ); } } Nine.update('2') Copy code
Note: 1. In ES6 class, when we define a component, we usually define a class, while static creates an attribute or method belonging to this class
2. The component is an instance of this class. The props and state of the component belong to this instance, so the instance has not been created
3. Therefore, static is not defined by react, and adding the static keyword means that the method will not be inherited by the instance, but will be called directly through the class, so this is also inaccessible
4.getDerivedStateFromProps also listens to the value through the static method. Please refer to skill 6 for details
10.constructor and super
Review:
1. Before talking about these two attributes, first review the ES6 function definition method
2. Every class defined in class mode has a constructor function by default. This function is the main function of the constructor, and this inside the function body points to the generated instance
3.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) is actually to get the properties and methods of the parent class this.state = { arr:[] } } render() { return ( <div> This is trick 10 </div> ); } } Copy code
11.PropTypes
Scenario: detecting the data type of the incoming sub component
Type checking PropTypes has been deprecated since React v15.5, please 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 verification 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 the format of the mailbox" ); } }, }; Copy code
Method 2: use the static attribute keyword static of ES7
class PropTypeTwo extends React.Component { static propTypes = { name:PropTypes.string }; render() { return ( <div> <div>{this.props.name}</div> </div> ); } } Copy code
12. Use class field declaration syntax
Scenario: you can initialize the local state without using the constructor, and declare the class methods by using the arrow function without binding them additionally
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 code
13. Asynchronous components
1. Scenario: route switching. If multiple pages are loaded synchronously, the route will be slow
2. Core API:
loader: components to be loaded
loading: page display component not loaded
Delay: delay loading time
Timeout: timeout
3. Use method:
Install react loadable and install syntax dynamic import for Babel plug-in 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>; } } Copy code
4.Loadable.Map()
Load high-level components of multiple resources in parallel
14. Dynamic components
Scenario: dynamic loading of components will be involved in a tab switch
In essence, it uses ternary expressions 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 components{oneShowFlag?2:1}</Button> {oneShowFlag?<FourteenChildOne></FourteenChildOne>:<FourteenChildTwo></FourteenChildTwo>} </div>); } } Copy code
If it is a single component, can short circuit operation be used
oneShowFlag&&<FourteenChildOne></FourteenChildOne> Copy code
15. Recursive component
Scene: tree component
Using react Fragment or div package cycle
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 has children, the recursive call itself item.children && item.children.length ? ( <Item>{item.children}</Item> ) : null} </React.Fragment> ); })} </div> ); } } Copy code
16. Controlled and uncontrolled components
Controlled component: the state of the component is controlled by the state value state or props of React
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>; } } Copy code
Uncontrolled component: the component is not controlled by the state value of React. It is controlled by the dom property or the ref of React
class NoControll extends React.Component { render() { return <div>{this.props.value}</div>; } } Copy code
Import Code:
export default class Sixteen extends React.Component { componentDidMount() { console.log("ref The value of the uncontrolled component obtained is:", this.refs["noControll"]); } render() { return ( <div> <Controll></Controll> <NoControll value={"This is the value passed in by an uncontrolled component"} ref="noControll" ></NoControll> </div> ); } } Copy code
17. High order components (HOCs)
17.1 definitions
1. It is similar to the definition of high-order function, and takes a component as a parameter or returns a component;
2. Function:
Extract duplicate code, realize component reuse, common scenarios, and page reuse;
Conditional rendering, control the rendering logic of components (rendering hijacking), common scenes, and permission control;
Capture / hijack the life cycle of the processed component, common scenarios, component rendering performance tracking and log management
17.2 implementation method
1. Attribute agent
import React,{Component} from 'react'; const Seventeen = WrappedComponent => 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 basic component' } render() { const {baseName} = this.state const {name} = this.props return <div> <div>The value of the basic component is{baseName}</div> <div>The value obtained by the high-level component attribute proxy is:{name}</div> </div> } } export default Seventeen(WrappedComponent) Copy code
2. Reverse inheritance
The principle is to use super to change the this direction of the component, and then some values of the container component can be processed in the component
const Seventeen = (WrappedComponent)=>{ return class extends WrappedComponent { componentDidMount() { this.setState({baseName:'This is the base component name modified through reverse inheritance'}) } render(){ return super.render(); } } } class WrappedComponent extends React.Component { state={ baseName:'This is the basic component' } render() { const {baseName} = this.state return <div> <div>The value of the basic component is{baseName}</div> </div> } } export default Seventeen(WrappedComponent); Copy code
18. Whether the element is displayed
Generally, ternary expression is used
flag?<div>show contents</div>:'' flag&&<div>show contents</div> Copy code
19.Dialog component creation
Dialog should be a component that is used more frequently. There are three different ways to create dialog: 1. Control whether the component is displayed through state
class NineteenChildOne extends React.Component { render() { const Dialog = () => <div>This is layer 1</div>; return this.props.dialogOneFlag && <Dialog />; } } Copy code
Method 2: create elastic layer through ReactDom.render - mount the outer layer of the root node
Control the display and hiding of elements through the native createElement,appendChild, removeChild and react's ReactDOM.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(); } }; Copy code
nineteen.jsx
twoSubmit=()=>{ Dialog.show('This is layer 2') } twoCancel=()=>{ Dialog.hide() } Copy code
20.React.memo
Function: when the input properties of class components are the same, you can use pureComponent or shouldComponentUpdate to avoid component rendering. Now, you can wrap the function component in react Memo to achieve the same function
import React from "react"; function areEqual(prevProps, nextProps) { /* If nextProps is passed into the render method, the returned result is the same as If the return results of prevProps passed into the render method are consistent, it returns true, Otherwise, it returns 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); Copy code
21.React.PureComponent
effect:
1.React.PureComponent is similar to React.Component in that both define a component class.
2. The difference is react Component does not implement shouldComponentUpdate(), but React.PureComponent implements it by shallow comparison of props and state.
3.React.PureComponent is used in the class, and React.memo is used in the function.
4. If the props and state of the component are the same and the content of the render is 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'}></TwentyOneChild> </div> ) } } Copy code
22.React.Component
Function: it is a react component based on ES6 class. React allows you to define a class or function as a component. To 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 skill 22</div> ) } } Copy code
23. Print false value in JSX
definition:
1. False value (virtual value) is a value recognized as false in the Boolean context;
2. The values are 0, '', '', '' ` `, null,undefined,NaN
export default class TwentyThree extends React.Component{ state={myVariable:null} render(){ return ( <div>{String(this.state.myVariable)}</div> ) } } Copy code
If the virtual value is directly displayed, it will be implicitly converted to false, so the page will not be displayed
24.ReactDOM.createPortal
Function: the element returned by the render function of the component will be mounted on its parent component. createPortal provides an excellent scheme for rendering child nodes to DOM nodes other than 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 through ReactDOM.createPortal Created content </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 add 1</Button> <p>Number of clicks: {this.state.clicks}</p> <Modal> <Child /> </Modal> </div> ); } } Copy code
In this way, the element is appended to the specified element
25. Use innerHTML in React
Scenario: some background return fields are in html format, so innerHTML attribute needs to be used
export default class TwentyFive extends React.Component { render() { return ( <div dangerouslySetInnerHTML={{ __html: "<span>This is rendered HTML content</span>" }}></div> ); } } Copy code
26.React.createElement
Syntax:
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 one span label") )} </div> ); } } Copy code
Principle: in fact, the dom of JSX is finally converted into js, which is 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 code
27.React.cloneElement
Syntax:
React.cloneElement( element, [props], [...children] ) Copy code
Function: this method is used to copy components, pass values to components or add properties
Core code
React.Children.map(children, child => { return React.cloneElement(child, { count: _this.state.count }); }); Copy code
28.React.Fragment
Function: React.Fragment allows you to aggregate a list of child elements without adding additional nodes in 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> ); } Copy code
29. Cycle element
Instead of encapsulating the v-for instruction in vue, it traverses through the map
{arr.map((item,index)=>{ return( <div key={item.id}> <span>{item.name}</span> <span>{item.age}</span> </div> ) })} Copy code
30. Set and get custom properties for DOM
Function: some values need to be passed 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> ); } } Copy code
31. Binding event
Scenario: the interaction will involve event clicking, and then clicking the selected value to pass parameters is also a very 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> ); } } Copy code
Use the method in the source code routes JS is used in detail
32.React-Router
32.1 difference between V3 and V4
1. In V3 or earlier versions of V, router and layout components are separated;
2.V4 is a centralized router. Through Route nesting, layout and page nesting are realized. Layout and page components are part of the router;
3. The routing rule in V3 is exclusive, which means that only one route is finally obtained;
4. Routes in V4 are inclusive by default, which means multiple; Can match and render at the same time If you want to match only one route, you can use Switch. Only one of the routes will be rendered. At the same time, you can add exact to each route to achieve accurate match Redirect and browser redirection. When many routes do not match, you can match them
32.2 use
import { HashRouter as Router, Switch } from "react-router-dom"; class App extends React.Component{ render(){ const authPath = '/login' // The default page returned when you are not logged in can be set by yourself let authed = this.props.state.authed || localStorage.getItem('authed') // After logging in, you can use redux to modify this value return ( <Router> <Switch> {renderRoutes(routes, authed, authPath)} </Switch> </Router> ) } } Copy code
In V4, Layout and page nesting are realized through Route nesting, and Switch switches routes
33. Style introduction method
Method 1:import
import './App.css'; Copy code
Mode 2: inline mode
import React from 'react'; const Header = () => { const heading = 'Head assembly' 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 assembly </div> ) } Copy code
34. Dynamically bind className
Principle: control className value through ternary expression
render(){ const flag=true return ( <div className={flag?"active":"no-active"}>This is skill 34</div> ) } Copy code
summary
These are the 34 skills of React summarized from the actual project development;