preface

This note is a summary of some of my essays on the project, and a transition from RC–>RF, which now exists more as a dictionary and memo form. There may be many deficiencies or even mistakes, please correct them.

Project startup and technology stack selection

  1. Project technology stack
  • React
  • React-Router-Dom
  • Redux + React-Redux + Redux-Thunk
  • Axios data request
  • LeanCloud Provides online data access for cloud services
  • AntDesign UI component library

1. Build React development environment

  1. Switch the mirror
Switch installation image source NPM config set registry https://registry.npm.taobao.org configuration can be successful in the following way to verify whether NPM config get registryCopy the code
  1. Initialize the React project
NPX create-react-app [Project name] NPM run start (YARN start) Starts the projectCopy the code
import React from 'react'; // View interaction import ReactDOM from 'react-dom'; // Reactdom.render (<App />, document.getelementbyid ('root'))Copy the code
  1. The Es7 React plug-in is commonly used
Imp import moduleName from 'module' imr import React from 'React' imd import {} from 'module' IMC RCC generates class component structure RFC The generator function component structure RFCREdux generates state machinesCopy the code

JSX syntax

Syntax sugar, the essence is to achieve more convenient effect virtual DOM and DIff algorithm rendering JSX structure

We need a data format that expresses a DOM structure

  1. Expressed through the virtual DOM
{
    tag:'div',
    type:'tag',
    attr:{
        'className':'App'
    },
}
Copy the code
  1. JSX DOM structure (React)
Let nodes = <div className="App"> asdfasdfa <span> I am span</span> </div>Copy the code
  1. JSX rendering component flow

JSX structure — Virtual DOM–Diff algorithm comparison — New virtual DOM– Real DOM

  1. Dynamic binding of data in JSX
  • String rendering
  • Basic operations (addition, subtraction, multiplication and division modules)
  • Template string
  • Three unary
  • A function call
  • Logical operations (and or not)
  • JSX nested
  1. Dynamic binding of properties and styles

Dynamic binding of className

<div className={isActive? 'box active':'box'}></div>Copy the code

Other attributes

  • input value\checked\disabled
  • img src

Notice that some of the attributes of a form element, for example value value needs to use defaultValue checkBox needs to use defaultChecked

<input defaultValue={str}/>
<input type="checkbox" defaultChecked={isCheck}/>
Copy the code

Iii. Component classification

Component names must begin with uppercase letters (an error occurs when a component is called without uppercase letters)

  1. Functional component

In React Lower versions, we called functional components, also known as stateless components. In React lower versions, you can use Hooks to make functional components have state

Export default function FnComp(){return <div> component structure </div>}Copy the code
  1. Class components

Import React,{Component} from ‘React’

Import React,{Component} from 'React' class ClassDemo extends Component{render(){return <h1> this is the class Component </h1>}} export default ClassDemoCopy the code

Definition of event function

  1. Normal function definition (define life cycle)

The this pointer must be corrected in constructor

Constructor (){constructor(){// provide this for ClassDemo. Constructor this.state = {isActive:false} this.handlebg = this.handlebg.bind (this) // Fix this to} handleBg(){ // [1] Define the event function using normal syntax. Note that this refers to let {isActive} = this.state; this.setState({ isActive:! IsActive // Trigger state change by event})}Copy the code
  1. How arrow functions are defined
handleBg = ()=>{ let {isActive} = this.state; this.setState({ isActive:! IsActive // [3] Trigger state change by event})}Copy the code

5. Component communication

If the child component is a function component, use the porps argument. If the child component is a class component, use this.props. If arguments need to be passed back, the parent component needs to pass a function, and the child component uses nested anonymous functions to pass back arguments

(1) Father-son communication props

  • Functional component

Accept props through the first parameter of the component

Import React from 'React' export default function Job(props) {// Job jobname={jobname}/> Return (<h3> jobname: {props. Jobname}</h3>)}Copy the code
  • Class components

Get the props parameter from this. Props

<ClassJob jobName ={jobname} salary={salary} handlesalary={this. handlesalary} /> Through this. Props parameter render () {let {jobname, salary, handleSalary} = this. Props return (< div > < h3 > position name: {jobname} < / h3 > < p > salary: {salary} K < / p > < button onClick = {() = > {handlesalary (independence idx, 5)}} > pay < / button > < / div >)}Copy the code

(2) Communication between son and father

The parent component passes event functions to the child component to change parent-child communication for the parent property

  1. Define state in the parent component
  2. Define an event function handleSalary in the parent component to modify state
  3. When a child component is called, the event function of the parent component is passed to the child component
Constructor (){super() this.state = {joblist:[{jobName :" front engineer ", salary:8}]}}Copy the code
handleSalary=(idx,m)=>{
    let {joblist} = this.state
    joblist[idx].salary += m
    this.setState({
      joblist
    })
  }
Copy the code
<ClassJob 
  jobname={jobname} 
  salary={salary} 
  handlesalary={this.handleSalary}
/>
Copy the code
  1. In the child component, event functions passed by the parent are triggered as needed, triggering a change in the parent component’s state

If you need to pass parameters, the child component calls with nested anonymous arrow functions

Render () {let {handlesalary} = this. Props let {handlesalary} = this. Props return (<div> <h3> {salary}K</p> {salary>=20? "' : < button onClick = {() = > {handlesalary (independence idx, 5)}} > pay < / button >} < / div >)}Copy the code

The parent component calls the child component method

If you are calling a subcomponent (>= [email protected]) from a method component, you can use the forwardRef and useImperativeHandle

const { forwardRef, useRef, useImperativeHandle } = React; const Child = forwardRef((props, ref) => { useImperativeHandle(ref, () => ({ getAlert() { alert("getAlert from Child"); }})); return <h1>Hi</h1>; }); const Parent = () => { const childRef = useRef(); return ( <div> <Child ref={childRef} /> <button onClick={() => childRef.current.getAlert()}>Click</button> </div> ); };Copy the code

2. If you are calling a child component from a class component (>= [email protected]), you can use createRef:

const { Component } = React; class Parent extends Component { constructor(props) { super(props); this.child = React.createRef(); } onClick = () => { this.child.current.getAlert(); }; render() { return ( <div> <Child ref={this.child} /> <button onClick={this.onClick}>Click</button> </div> ); } } class Child extends Component { getAlert() { alert('getAlert from Child'); } render() { return <h1>Hello</h1>; }}Copy the code

6. Data rendering

(1) List rendering

{
  this.state.joblist.map((job,index)=>{
    return <ClassJob />
  })
}
Copy the code

(2) conditional rendering

{salary>=20 ? <button> </button>}Copy the code

Get the real DOM

Large-scale use of administrative focus, text selection, or media playback is not recommended.

Trigger the forced animation. Integrate third-party DOM libraries. The document

  1. Use createRef to generate a property myInput to get the DOM
import React, { Component,createRef } from 'react'
this.myInput = React.createRef()
Copy the code
  1. Bind this attribute via ref to a node element in the specified JSX
<input type="text" ref={this.myInput} onKeyUp={this.handleInput}/>
Copy the code
  1. In the rest of the component’s logic, use this.myInput to get the real DOM and manipulate it. Note that createRef is used instead of onchange events
handleInput=(ev)=>{ let v = this.myInput.current.value if(ev.keyCode===13){ let v = this.myInput.current.value this.setState({ msglist:[ ...this.state.msglist, V]}, () = > {/ / a setState after the execution will trigger the callback enclosing myInput. Current. The value = '})}}Copy the code

Fix setState async callback

Fix setState asynchrony: Use callbacks (note the callback hell problem)

this.setState({},()=>{}) this.setState({ msglist:[ ...this.state.msglist, V]}, () = > {/ / a setState after the execution will trigger the callback enclosing myInput. Current. The value = "})Copy the code

Life cycle function

**### ** PureComponent

Automatic recognition of differences between old and new state data for selective updating

Commonly used life cycle functions

Life cycle function diagram

Initialization phase

  • constructor
  • render
  • ComponentDidMount initiates an online request to get a packet

Update the stage

  • render
  • componentDidUpdate

Destruction of phase

  • componentWillUnmount

Ten, leancloud

Analog interface

Application list usage details

11. Webpack introduction

Project development packaging tool

The document

  1. Modular, componentized development — Webpack — code integration
  2. Advanced syntax (ES6 syntax, React syntax) -webpack- syntax that browsers can recognize
  3. Provide a convenient development environment

Differences between plugins and Loaders

  • Loader gives WebPack the ability to load and parse non-javascript files. Components for parsing different types of syntax (e.g. React)

    • Use babel-loader to help Webpack compile react syntax
    • Css-loader style-loader parses the style file and its syntax
  • Plugin can extend the functionality of WebPack to make it more flexible. A number of events are broadcast during the life cycle of a Webpack run, and the Plugin can listen for these events and change the output when appropriate through the API provided by Webpack.

  • Babel is a JavaScript compiler.

    • React presets, ES syntax presets, etc

Devserver configuration use

Start a local service, listen for code changes, repackage the code, and automatically refresh the browser for preview

HOC (Hight- order-Component) high-level Component

A function that handles an existing component, appends a new structure or method to the component, and returns the new component

HOC document

  1. Usage scenarios

React-router withRouter() injects routing data into components. React-redux connect() injects store data into components

Xxix. 8 Hooks new features (Functional programming)

Common Hooks feature

(一)、useState

Let functional components have state and action methods

Import React,{useState} from 'React' let [num,setNum] = useState(100) import React,{useState} from 'React' let [num,setNum] = useState(100Copy the code

(二)、useEffect

1. The first argument receives a function as an argument. 2. The second argument receives a dependency list, and only executes function 3 when the dependency is updated. Returns a function that executes first, then the argument function

UseEffect (() = > {setList ([' zhao ', 'extinction teacher 111']) (async () = > {let res = await getTodoList () setList (res) data. The results)}) ()}, []) // Dependencies can be added as appropriateCopy the code

(三)、useLayoutEffect

UseLayoutEffect is executed after DOM updates; UseEffect is executed after render ends. After executing the sample code, useLayoutEffect always executes before useEffect, because rendering ends after DOM updates or still ends

4. UseMemo

Use react. memo to optimize performance: Store a variable and pass a create function and dependency. Create functions return a value. Only when the dependency changes will the function be called again and return a new value. In simple terms, the effect is to make the function in the component follow state updates (that is, the function function in the optimization function component) 1. Accept a function as a parameter 2. Also accept a second parameter as a dependency list (compare with useEffect and useLayoutEffect) 3. It returns a value. The return value can be any function, object, etc

// Use useMemo to wrap the initial value of the subcomponent; Const info = {name: 'Even', age: 22} const info = useMemo(() => {// Wrap the child to initialize data return {name: 'Even', age: 22}},[]) // Dependencies can be added appropriately or import React, {useContext, useMemo} from 'React '; export default (props= {}) => { const { state, dispatch } = useContext(MyContext); return useMemo(() => { return ( <div></div> }, [state.count, state.number. state.step, dispatch]); }Copy the code

useCallback

Like useMome, useCallback is optimized for the callback function passed in and returns a function; UseMemo can return any value, function, object, etc

function Parent () { const [num, setNum] = useState(1) const [age, SetAge] = useState(18) const getDoubleNum = useCallback(() => {console.log(' getDoubleNum ${Num} ') return 2 * Num},[Num]) Return (< div onClick = {() = > {setNum (num = > num + 1)}} > this is a functional component -- -- num: {getDoubleNum ()} < br > < br > value of age -- -- -- the age: { age } <br></br> set.size:{set.size} <Child callback={ getDoubleNum() }></Child> </div> ) } function Child(props) { UseEffect (() => {console.log('callback updated ')},[props. Callback]) return (<div> Subcomponent getDoubleNum{props. Callback} </div>)}Copy the code

Sub-component update optimization simple summary use scenario judgment:

If a function is passed to the child, use **useCallback** + otherwise use **useMemo**Copy the code

(六)、useRef

UseRef is not just used to manage DOM refs; it is equivalent to this and can store any variable that the parent component gets its child component methods, parameters, and manipulates its child components

// Parent component: const detailInfoRef = useRef<DrawerInstance>(null); // We need to wrap the subcomponent with the forwardRef and useImperativeHandle to pass the parameters, for example:  import { forwardRef, memo, useImperativeHandle } from 'react'; const DrawerBillGoods = forwardRef<propsType,refType>(({percent}, ref) => { const { openDrawer, closeDrawer } = useDrawer(); useImperativeHandle(ref, () => ({ openDrawer, closeDrawer, })); Return (<div>I am update every {percent} seconds</div>)}) // Memo () The second parameter controls whether to refresh export default Memo (CSlider, (prevProps, nextProps) => { return prevProps.percent === nextProps.percent; } // Export default memo(SellerDrawer, (next, prev) => _. IsEqual (next-data, prev.data),)Copy the code

(七)、useContext

We need to introduce useContetx, createContext and we create a context handle on createContext to determine the scope of the data sharing and distribute the content through the value in the child component, The useContext(Context handle) is used to retrieve data

Const Context = createContext(null) function StateFunction () {const [num, SetNum] = useState(1) return (<div> <button onClick={()=> setNum(num => num+1)}> Num} < context. Provider value={num}> // determine the scope and distribute the value <Item3></Item3> <Item4></Item4> </ context. Provider> </div>)} function Item3 () {const num = useContext(Context)} Item3 () {const num = useContext(Context)}Copy the code

(八)、useReducer

> 1. For complex state operation logic of a single component and nested state objects, it is recommended to use useReducer. You can use Redux in functional components using useReducer. The purpose is to obtain the desired state from the state management toolCopy the code

Usage method 1

function ReducerDemo(){ const [ count , dispatch ] =useReducer((state,action)=>{ switch(action){ case 'add': return state+1 case 'sub': return state-1 default: Return state}},0) return (<div> <h2> now score is {count}</h2> <button onClick={()=> Dispatch ('add')}>Increment</button> <button onClick={()=>dispatch('sub')}>Decrement</button> </div> ) }Copy the code

Usage 2

Const store = {age:18, num:1} const reducer = (state=store, action) => { switch(action.type){ case 'add': return { ... state, num: action.num+1 } default: return { ... Function StateFunction () {const [state,dispacth] = reducer ()  <div> <button onClick={ () => { dispacth({ type: 'add', num: Num :{state. Num} </div>) {state.Copy the code

Fragment code

< > < >

Import React,{Fragment} from 'React' export default function Frag1() {return (<Fragment> <p> <p> <p> <p> <p> </Fragment> ) }Copy the code

Props. Children slot

Children </h1> {this.props. Children} </div>) <SlotDemo> // New tag passed in when <p> <p> New tag passed in </p> </SlotDemo>Copy the code

PropTypes type validation

// In the component, Install introduced using the import PropTypes from 'prop - types' PropTypeDemo. PropTypes = {/ / to add type validation jobname class components: PropTypes. String, <PropTypeDemo jobName =" front-end developer "salary={20}/>Copy the code

Context component communication

It can be replaced by a state machine

  • Using the process
    • Defining a Context object
    • Use providers in components to provide data
    • Extract Context data in the other component CompC

React routing modules

Imprint Chinese react-router document

(1) Basic use

  1. The installation
yarn add react-router-dom
Copy the code
  1. Wrap BrowserRouter or HashRouter around your App component
import {BrowserRouter} from 'react-router-dom'
ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);
Copy the code
  1. Use Route mapping where components need to be displayed dynamically (such as in the Home component)
<Route path="/frag" Component ={FragDemo}/> <Route path="/frag" exact Component ={FragDemo}/> //exact Matches the pathCopy the code
  1. Route switching is implemented using Link
<Link to="/frag">Fragment demo </Link> // NavLink has dynamic activation effect </Link>Copy the code

(2) Route transmission parameters

  • Sets the route parameter
<Route path="/frag/:id" component={FragDemo}/>
Copy the code
  • Pass route arguments
<Link to="/frag/2333"></Link>
Copy the code
  • Extract routing parameters and use them
<h2> Routing parameters: {props.match-params. id}</h2> Functional component routing parameters in the props class component routing parameters in thisCopy the code

(3) programmed navigation

  • The binding event
  • Triggering route Switchover

== Programmatic navigation and parameter passing ==

Handerprod (target){// Do not pass the parameter // this.props.history.push(target) // Pass the parameter method 1: State // this.props.history. Push (target,66666) props.location.state this.props.history.push({ pathname:target, state:{ id:88888 } }) }Copy the code

(4) Routing nesting

Refer to Product/index.js for the main route configuration ‘basic usage’ process

(V) Route guard

The component returned by the method function of the Render property is rendered to the corresponding Route location

<Route path="/product" render={()=>{// If (isLogin){return <Product />}else{return <Login handleLogin={this.handleLogin}/>}}}/>Copy the code

Switch and redirection

When the routes wrapped around the Switch components change, the Switch will match the routes in sequence. If one path succeeds, the subsequent routes will not be matched

<Switch>
  <Route path="/effect" component={EffectOnline}/>
  
  <Route path="/404" component={NotFound}/>
  <Redirect from="*" to="/404"/>
</Switch>
Copy the code

(7) withRouter can be used as required

The component returned by the route guard also does not have this.props, so you need to use withRouter manually

By default, there is no routing object in this.props inside a component that is not presented via routing bootstrap

WithRouter allows this. Props to have routing objects inside such components; For example, the default presentation component home uses this.props

class Home extends Component {}
export default withRouter(Home)
Copy the code

(8) Analysis of routing principle

Handwritten React routing

  1. Link component
  • Change the hash value with the A tag
<Link to="/pro">Copy the code
  1. The Route component
  • Listen for hash changes in the browser address bar onHashChange
  • Check the path property of the Route component against the hash path
<Route path="/pro1" component={component}/>Copy the code

Introduction to Redux

The document

  1. Redux

State machine data dynamic changes, need to manually subscribe

  1. Redux + React-Redux

No manual subscription is required

  1. Redux + React-Redux + @rematch/core

Syntax is very close to vuex design mode (Observer mode)

(I) Core concepts

  • Store Generates state machine data
import {createStore} from 'redux' import reducer from '.. /reducer' let store = createStore(reducer) export default storeCopy the code
  • Reducer produces different data packets according to different needs of users
  • Action Describes the object that the user needs
{type:'increment', // Action description payload:10 // Action carries parameters}Copy the code

(二)、Redux

  1. reducer

Must be pure functions with predictable results for packets

Function reducer(state,action){if(action.type){return data // return data based on type type sent by Dispatch}}Copy the code
  1. Store the state machine
  • The method used by getState() to getState machine data (the data is not dynamic)
  • Subscribe (()=>{}) Responds to changes in state machine data in the View view layer
  • Dispatch () view The view layer sends an action description to the Store state machine. Reducer returns different values based on different types
componentDidMount(){ this.setState({ num:store.getState() }) store.subscribe(()=>{ Console. log('Num component senses store data change ',store.getState()); this.setState({ num:store.getState() }) }) } <button onClick={()=>{ store.dispatch({ type:'increment' }) }}>+</button>Copy the code

Redux + react-redux

The react – redux document

Delete goods: Put this method in the Reducer

  • Introduce CONNECT and inject the state machine
  • Import the prepared ActionCreator
  • Pass ActionCreator into Connect to make it a dispatch for the action
  • Call the reducer method

    with an event
  1. action

Do not perform operations such as local storage related to an object that describes the data change mode in the reducer. Do not perform operations in the corresponding position in the Reducer

{
  type:'',
  payload:''
}
Copy the code
  1. ActionCreator

Some method functions that generate actions

function increment(){
  return {
    type:'',
    payload:''
  }
}
Copy the code
  1. Install the react – story
yarn add react-redux
Copy the code
  1. In the project entry file index.js, inject the Store state machine from the root component
import {Provider} from 'react-redux'
import store from './store'
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
Copy the code
  1. Extract == data == from the store state machine in num.js

Data has been injected in the Reducer, so it is unnecessary to import

<! The connect method accepts two parameters: mapStateToProps and mapDispatchToProps. They define the business logic of the UI components. The former is responsible for the input logic, which maps state to the UI component's parameters (props), and the latter is responsible for the output logic, which maps user actions on the UI component to actions. Import {connect} from 'react-redux' // class Num extends Component {} const mapStateToProps = (state)=>{// [2] {// [3] The value of this return, as the Num component count:state.?? // Count is the name of the props}} export default connect(mapStateToProps)(Num) // mapStateToProps is used to reference the data in the state machine to the props of the current componentCopy the code
  1. In the btn.js component, extract the Dispatch == method == in the state machine

The method requires importy to be introduced

Import React, {Component} from 'React' import {connect} from 'React' import {connect} from 'React -redux' import {decrement, increment } from '.. /.. / / / action/index '[2] prepared actionCreator class Btn extends Component {render () {let {children, increment and decrement} = This. Props // [4] Rement has changed to a dispatch let disp = children=='+'? increment : decrement return ( <button onClick={disp}>{children}</button> ) } } export default connect(null,{ increment, //【3】 Rement in connect decrement})(Btn)Copy the code

Redux + react-redux + redux-thunk

The document

Redux-thunk enables the state manager to have asynchronous action capabilities

Location where the asynchronous request originated

  • Internal component initiation? Asynchronous requests are used to render components
  • Asynchronous action? Asynchronous requests are used to manipulate the state machine

What scenario packets are appropriate for a state machine?

  • Sharing across components
  • Shopping cart, personal information, address management, etc
  1. The installation
yarn add redux-thunk
Copy the code
  1. Import and configure in store/index.js
import {createStore,combineReducers, applyMiddleware} from 'redux' import thunk from 'redux-thunk' let reducer = combineReducers({cartReducer,countReducer}) Let Store = createStore(Reducer,applyMiddleware(thunk))Copy the code
  1. Define and implement asynchronous actions in action/index.js
Export const incrementSync = (payload)=>{// Asynchronous action return dispatch =>{// When an asynchronous action is triggered, the dispatch will be intercepted. // After the asynchronous operation is complete, Action setTimeout(()=>{dispatch(increment())},2000)}}Copy the code
  1. Invoke asynchronous actions in the component

Refer to btnsync.js as the process for calling synchronous action

(V) The process of using @rematch/core

The document

Simplify the process of defining store state machines by referring to the learning-rematch branch of the React /day05/ learning-redux project

Redux, which is fixed by the HOOKS of useSelector, useDispatch.

import { useSelector, useDispatch } from 'react-redux'; import { addAction, reduceAction } from './store/actions/action'; const App = (props: any) => { const { num } = useSelector((state: any) => state.numReducer); const dispatch = useDispatch(); Return (< > < h2 > global data store: {num} < / h2 > < button onClick = {() = > {dispatch (addAction ())}} > + < / button > < button onClick = {() = >  { dispatch(reduceAction()) }}>-</button> </> ) }Copy the code

Customize the React project

Goals achieved:

How to turn off EsLint How to use antD’s custom theme with less syntax in projects

  1. Customize the package required for configuration

react-app-rewired customize-cra

Customize-cra provides a specific configuration item called react-app-rewired that allows usto launch the project in a new way and validate the configuration items provided above

(1) Alias configuration of resource reference path

@ points to SRC. @ Action points to SRC/Action

Jump to config-overrides. Js configuration file

addWebpackAlias({
    '@':path.resolve(__dirname,'src'),
    '@action':path.resolve(__dirname,'src/action'),
    '@api':path.resolve(__dirname,'src/api'),
    '@assets':path.resolve(__dirname,'src/assets'),
    '@components':path.resolve(__dirname,'src/components'),
    '@utils':path.resolve(__dirname,'src/utils')
})
Copy the code

(2) The process of custom configuration

  1. Install dependencies
yarn add react-app-rewired customize-cra --dev
Copy the code
  1. Create the config-overrides. Js file in the project root directory and configure it
Const {override, disableEsLint} = require('customize-cra') module.exports = override(disableEsLint() // disableEsLint code testing)Copy the code
  1. Adjust the scripts command in package.json
"Scripts ": {- "start": "react-scripts start", original command + "start": "react-app-rewired start", new command}Copy the code

(3) addLessLoader configuration

  1. Install the style precompiled package
yarn add --dev less less-loader
Copy the code
  1. Adjust the config-overrides. Js configuration file
Addlessoptions: {javascriptEnabled: true, modifyVars: {'@primary-color': '#A80000'},}})Copy the code

(IV) antD custom topic process

  1. Define the theme color JS module

Refer to the theme. Js

  1. Adjust the config-overrides. Js configuration item to introduce theme and configure it

  2. Change antD.css in the index.js entry file to antD.less

(v) The configuration process of decorators

Syntactic sugar

  1. Before using the decorator syntax
class Login extends Component{

}
export default connect(mapState)(Login)
Copy the code
  1. Use decorators
@connect(mapState)
class Login extends Component{

}
Copy the code
  1. Decorator syntax document

About decorator syntax

@testable
class MyTestableClass {
  // ...
}

function testable(target) {
  target.isTestable = true;
}

MyTestableClass.isTestable // true
Copy the code
  1. Install bebel library
yarn add @babel/plugin-proposal-decorators
Copy the code
  1. Configure config – overrides. Js

To allow scaffold environments to support decorator syntax

The document

  1. Vscode recognition configuration for decorator syntax

If the code works, but vscode prompts a syntax error, you need to configure it

"settings": {
    "problems.decorations.enabled": false,
    "javascript.implicitProjectConfig.experimentalDecorators": true
},
Copy the code

Real combat +AntDesign

· Use the Form and enter LeanCloud data

Form.useform () const [Form] = form.useform () /* Connect the generated Form instance to the Form element, set the Form attribute to the Form element that you want to control. NewVal is the new value */ form = {form} /* setFieldsValue sets the value of the form item, where, */ form.setFieldsValue({name:newVal}) 2 Class component, FormRef = react.createref () // Bind ref = {this.formref} in the Form // make changes where you want to change the value of form.item this.formRef.current.resetFields();Copy the code
  1. Custom adjustments to form layout structure
  • labelCol
  • wrapperCol
  • .
  1. Form configuration items
  • InitValue Initializes packet Settings
  1. Methods for form control (setting defaults, resetting methods)
  • onFinish
  • Form.setfieldsvalue sets the form data
  1. How to fill in the form verification
  • rules
    • required
    • email
    • .

· Use of table components

  1. Columns Indicates the configuration item of the table component appearance
  • The role of dataIndex
  • The render method function renders the required content
  1. The dataSurce data packet format

  2. pagination={{}}

Real rich text editor

  1. What is rich text?
  • Rich text carries tags and styles
    • V-html can be used in VUE
    • Small program rich-text
    • uniapp rich-text

How to integrate third parties in React

wangEditor Ueditor tinymce

Rich text editors use processes

  1. Integrate rich text editor flows in React
  • Installation and introduction
yarn add wangeditor
import E from 'wangeditor'
Copy the code
  • Gets the container DOM node createRef of a rich text editor

  • Initialize the editor in componentDidMount in the component that needs to display a rich text editor

This.e = new e(this.editor.current) // Rich text editor instance this.e.cate () this.e.config. ZIndex = 1Copy the code
  • Extracts rich text editor content by specifying methods
let intro = this.e.txt.html()
Copy the code

Actual Combat · Gaud map

Integrate the Map API with React

Amap API

  1. Log in
  2. Create an application and create a key
  3. Implement the Amap method package (js package) in the project public/index.html
  4. Initialize the map by calling the AMap method in the component that needs to display the map
var map = new AMap.Map(this.container.current, {
    resizeEnable: true
});
Copy the code

Combat · User role control

Different means of permission control

  • Log in to roles
  • Roles filters routing packets and dynamically renders navigation menus that meet permissions
  • Roles is used to filter routing packets and dynamically render routes that meet permission requirements
  • Before performing database operations, the backend needs to determine the current user permissions [Backend development completed]
  • Button level permission control [According to the actual situation]
  • Routing and mapping data packets dynamically delivered on the server side [Optional]

Route add rolus[] key-value pair [with access role], later optimize button level permissions, [{user:root,C:true,R:false]},{user:other,R:true}]

  • Determine the menu and route rendering based on the roles stored in the state machine after login
    • The includes(a) array API is used to determine whether an array contains a
let bool = roles.includes(role) && title
return bool 
    ? 
    <Menu.Item key={itm.path}>{itm.title}</Menu.Item>
    : ''
Copy the code
  • Route control needs to use 404 pocket bottom, rendering the basic steps with the menu, need to cancel the normal route rendering extra 404 components

Combat · Basic use of Echarts

Echarts website

  1. The installation
yarn add echarts
Copy the code
  1. Introduce methods provided by Echarts in components that need to present diagrams
// import * as echarts from 'echarts'Copy the code
  1. Prepare a DOM container for the diagram presentation

  2. Call echarts’s init method to initialize the diagram and do the custom configuration

var myChart = init(this.chart1.current); // Specify the chart configuration item and data var option = {}; // Display the chart using the configuration items and data you just specified. myChart.setOption(option);Copy the code

The react when packaged

"Build ": "react-scripts build", change to "build": "react-app-rewired build",Copy the code

Delete rows

onOk : async()=>{ let res= await cfyDel(text.objectId) if(res.status===200){ let {data} = this.state console.log(data) for(let i=0; i<data.length; i++){ if(data[i].objectId===text.objectId){ data.splice(i,1) break; }} // let newRes = await cfyList() // let newData = newres.data.results.map (item=>{// add key manually // return{//... item, // key:item.objectId // } // }) // this.setState({data:newData}) this.setState({data:[...data]}) this.props.history.push({ pathname:"/admin/cfy/list" }) } },Copy the code