1. Introduction

React video and! [react official website](https://zh-hans.reactjs.org/)Copy the code

1. Get ready to sail

Create project: NPX create-react-app my-app Open project: CD my-app Start project: NPM start Expose configuration item: NPM run eject File structure: │ ├─ ├─ manifest.html │ ├─ manifest.html │ ├─ manifest.src source Code │ ├─ app.css ├─ App.js Root Component ├─ App.test.js ├─ index.css Global Style ├─ index.js import File ├─ logo.svg ├─ serviceWorker.js Pwa Support ├─ package.json NPM rely onCopy the code

Entry file: webpack.config.js

// Check if TypeScript is setup const useTypeScript = fs.existsSync(paths.appTsConfig); // style files regexes const cssRegex = /\.css$/; const cssModuleRegex = /\.module\.css$/; const sassRegex = /\.(scss|sass)$/; const sassModuleRegex = /\.module\.(scss|sass)$/; entry: [// WebpackDevServer client, It implements the development hot update function isEnvDevelopment && require. Resolve (' react - dev - utils/webpackHotDevClient '), / / application entry: src/index paths.appIndexJs, ].filter(Boolean),Copy the code

2.JSX

JSX is a syntax extension to JavaScript, similar to the template language. JSX is a JS object and an expression.

const name = 'world' const element = <h1>Hello, {name}! </h1> // function formatName(user) {return user.firstName + "+ user.lastName} const user = {firstName: 'Harper', lastName: 'Perez' }; const element = ( <h1> Hello, {formatName(user)}! </h1> ); ReactDOM.render( element, document.getElementById('root') ); function getGreeting(user) { if (user) { return <h1>Hello, {formatName(user)}! </h1>; } return <h1>Hello, Stranger.</h1>; } const greet = <div>good</div>; const jsx = <div>{greet}</div>; // Because JSX is syntactically closer to JavaScript than HTML, React DOM uses camelCase to define attribute names instead of the naming convention for HTML attribute names. const element = <div tabIndex="0"></div>; const element = <img src={user.avatarUrl}></img>; // conditional statement const show = true; const greet = <div>good</div>; const jsx = ( <div> {show ? } {show && greet} </div>); Const element = (<h1 className="greeting"> Hello, world! </h1> ); const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world! '); Const element = {type: 'h1', props: {className: 'greeting', children: 'Hello, world! '}}; // array const a = [0, 1, 2]; Const JSX = (<div> <ul> {/* diff) const JSX = (<div> <ul> {/* diff) The key value must be the only * /} {arjun ap (item = > (< li key = {item} > {item} < / li >))} < / ul > < / div >). // import logo from "./logo.svg"; Const JSX = (<div> {/* Attributes: static values in double quotes, dynamic values in curly braces; Special treatment for class, for, etc. */} <img src={logo} style={{ width: 100 }} className="img"/> </div> ); // CSS modularity import style from "./base.css"; <img className={style.logo} />Copy the code

3. Component (the component name is fully humped, such as Clock, ClockName, capitalized first word)

1. The class components

Class components typically have state and life cycles that inherit from Component and implement the Render method.

import ClassComponent from './ClassComponent'; <ClassComponent /> // Use import React, { Component } from 'react' export default class Clock extends Component { constructor(props) { super(props); this.state = { date: New Date()}} componentDidMount() {this.timer = setInterval(() => {this.setState({Date: new Date()}); }, 1000); } componentWillUnmount () {/ / component uninstall before execution clearInterval (enclosing the timer)} componentDidUpdate () {/ / component update (has been) console.log('componentDidUpdate') } render() { const { date } = this.state return ( <div>{date.toLocaleTimeString()}</div> ) } }Copy the code

2. The function component

Function components are usually stateless, just focus on the presentation of the content and return the render results.

Difficulty: understanding and using dependencies

import { FunctionComponent } from './FunctionComponent'; <FunctionComponent /> import React, { useState, useEffect } from 'react'; export function FunctionComponent(props) { const [date, setDate] = useState(new Date()); UseEffect (() => {console.log('uesEffect') const timer = setInterval(()) => { setDate(new Date()); }, 1000); Return () => clearInterval(timer) // Execute}, []); // the dependency (useEffect) is executed again if it changes, ComponentDidUpdate return (<div> {date.tolocaletimeString ()} </div>)}Copy the code

4. Use setState correctly

SetState (partialState, callback) 1. PartialState: object | function used to generate a merger with the current state of subsets. Callback: callback is called after function state is updated.Copy the code

1. Do not modify state directly

This.setstate ({comment: 'hello'}) constructor is the only place to assign a value to this.stateCopy the code

2. State updates can be asynchronous

React may combine multiple setState() calls into a single call for performance reasons. Because this.props and this.state may update asynchronously, you should not rely on their values to update the next state. // error this.setState({counter: this.state.counter + this.props. Increment}); This.setstate ((state, props) => ({counter: state.counter + props. Increment})); Import React, {Component} from "React "; export default class SetStatePage extends Component { constructor(props) { super(props); this.state = { counter: 0 }; } changeValue = v => { this.setState({ counter: this.state.counter + v }); console.log("counter", this.state.counter); }; setCounter = () => { this.changeValue(1); // console.log("counter", this.state.counter); }; render() { const { counter } = this.state; return ( <div> <h3>SetStatePage</h3> <button onClick={this.setCounter}>{counter}</button> </div> ); ChangeValue = v => {this.setState({counter: This.state.counter + v}, () => {console.log("counter", this.state.counter); }); }; // 2. Use timer setTimeout(() => {this.setCounter(); }, 0); / / 3. Modify state componentDidMount native event () {/ / mount document. Body. AddEventListener (' click ', enclosing changeValue, false)} / / summary: SetState is asynchronous only in synthesized events and lifecycle functions, and synchronous in both native events and setTimeout, where asynchrony is actually batch updating (hence merging). The above is the synchronization operation, where synchronization means that the latest value is retrieved immediately after the current setState execution.Copy the code

3. State updates will be annexed

constructor(props) { super(props); this.state = { posts: [], comments: [] }; } componentDidMount() { fetchPosts().then(res => { this.setState({ posts: res.posts }); }); fetchComments().then(res => { this.setState({ comments: res.comments }); }); } changeValue = v => { this.setState({ counter: this.state.counter + v }); }; setCounter = () => { this.changeValue(1); this.changeValue(2); };};}; State: changeValue = v => {this.setState(state => ({counter: state.counter + v}))); }; setCounter = () => { this.changeValue(1); this.changeValue(2); };Copy the code

5. Component Composition and Inheritance (Children)

1. Not to be identified

import React, { Component } from 'react'; import Layout from './Layout'; Export default class HomePage extends Component {render() {return (<Layout title=" HomePage "> <div> home page </div> </Layout> ); } } import React, { Component } from 'react'; export default class Layout extends Component { componentDidMount() { const { title } = this.props document.title = title } render() { const { children } = this.props console.log(children) // {$$typeof: Symbol(react.element), type: "div"...... return ( <div> {this.props.children} </div> ) } }Copy the code

2. Named (pass object in)

import React, { Component } from 'react'; import Layout from './Layout'; Export default class HomePage extends Component {render() {return (<Layout title=" HomePage "> {// HomePage {} {// (< div > < h3 > home page < / h3 > < / div >), TXT: 'text' btnClick: () = > {the console. The log (' button ')}}} < / Layout >); } } import React, { Component } from 'react'; export default class Layout extends Component { componentDidMount() { const { title } = this.props document.title = title } render() { const { children } = this.props console.log(children) // content: {$$typeof: Symbol(react. Element), type: "div", key: null, ref: null, props: {... },... }... return ( <div> {children.content} {children.txt} <button onClick={children.btnClick}>btn</button> </div> ) } }Copy the code

6. Life cycle

Lifecycle methods for performing custom functionality in different phases of a component. Lifecycle methods are available when a component is created and inserted into the DOM (that is, the mounting phase), when a component is updated, when a component is unmounted, or when it is removed from the DOM.

Life cycle:

React V16.3 previous lifecycle:

ComponentDidMount // When the component is rendered for the first time, the DOM node has been generated, you can call the Ajax request here, and the component will be rendered again after the setState data is returned. ComponentWillUnmount // This is where components are unmounted and data is destroyed. (timer, to monitor events to remove) componentWillReceiveProps (nextProps) / / in the parent component change after the use of props need to render the component, ShouldComponentUpdate (nextProps, nextState) shouldComponentUpdate(nextProps, nextState) is not implemented for the first rendering. Rerendering of the React parent will result in rerendering of all of its children. In this case, we do not need to re-render all of the children, so we need to make decisions in the life cycle of the children. In React, when setState changes, components will enter the process of re-rendering. Return false prevents components from updating. The componentWillUpdate and componentDidUpdate life cycles are no longer implemented. Render () // The render function inserts the JSX generated DOM structure. React generates a virtual DOM tree. At each component update, react uses its diff algorithm to compare the old and new DOM trees before and after the update.Copy the code

Life cycle after V16.4:

The three lifecycle functions that may be deprecated in V17 are replaced with getDerivedStateFromProps, plus UNSAFE_ for current use: ComponentWillMount componentWillReceiveProps componentWillUpdate introduced two new life cycle function: Static getDerivedStateFromProps getSnapshotBeforeUpdate If you do not want to manually prefix the deprecated life cycle with UNSAFE_, use the following command. NPX react-codemod rename-unsafe-lifecycles <path> Static getDerivedStateFromProps(props, State) getSnapshotBeforeUpdate(prevProps, prevState) getDerivedStateFromProps is called before the Render method is called, and is called both during the initial mount and during subsequent updates. It should return an object to update state, and if null is returned, nothing is updated. GetSnapshotBeforeUpdate () is called before the last render output (submitted to the DOM node). It enables the component to capture some information (for example, scroll position) from the DOM before changes are made. Any return values from this life cycle are passed to componentDidUpdate(prevProps, prevState, Snapshot) as parameters (Snapshot).Copy the code

7. Redux (similar to vuex)

Redux Docs also has free video learning

There is a considerable amount of data that changes over time; Your state needs to have a single reliable data source; You feel that putting all the state in the topmost component is no longer sufficient; The state of a component needs to be shared.

Install: NPM install redux –save

CreateStore import {createStore} from 'redux' const func = (state = 0, - > state const store = createStore(func) - > state const store = createStore(func) Store. Subscribe (() => {console.log("subscribe"); this.forceUpdate(); // This.$forceUpdate(); // this.setState({}); });Copy the code

8.react-redux

The react – redux document

NPM install react-redux –save

React-redux provides two apis: 1. Provider provides store for descendant components; 2. Connect provides data and change methods for components (parameters in Connect: state and event mappings)Copy the code
import React from 'react' import ReactDom from 'react-dom' import App from './App' import store from './store/' import {  Provider } from 'react-redux' ReactDom.render( <Provider store={store}> <App/> </Provider>, document.querySelector('#root') )Copy the code
import React, { Component } from "react"; import { connect } from "react-redux"; class ReactReduxPage extends Component { render() { const { num, add, minus, dispatch } = this.props; return ( <div> <h1>ReactReduxPage</h1> <p>{num}</p> <button onClick={() => dispatch({type: 'ADD'})}>add</button> <button onClick={add}>add</button> <button onClick={minus}>minus</button> </div> ); }} export default connect(// state mapping mapStateToProps state => ({num: state}), {// Issue event mapping add: () => ({type: "add"}), minus: () => ({type: "minus"}) } )(ReactReduxPage);Copy the code

9.react-router

NPM install react-router-dom –save

Router-router, link-link, route-route, exclusive-switch, and redirection-Redirect all exist as components. Children > Component >render These three are mutually exclusive and you can only use one of them. Children: func Sometimes, if you need to render something regardless of whether the location matches or not, you can use children. It works exactly the same as render, except that the location is rendered regardless of whether it matches. But when you use render, you're just calling a function. Render only when the location matches. Component: Component is rendered only when the location matches.Copy the code
import React, { Component } from "react"; import { BrowserRouter as Router, Route, Link } from "react-router-dom"; export default class RouterPage extends Component { render() { return ( <div> <h3>RouterPage</h3> <Router> <Link To = "/" > home page < / Link > < Link to = "/ user" > user center < / Link > {/ * root routing to add exact, } <Route exact path="/" Component ={HomePage} //children={() => <div>children</div>} //render={() => <div>render</div>} /> <Route path="/user" component={UserPage} /></Router> </div> ); } } class HomePage extends Component { render() { return ( <div> <h3>HomePage</h3> </div> ); } } class UserPage extends Component { render() { return ( <div> <h3>UserPage</h3> </div> ); }}Copy the code

404 page (set a route with no path at the end of the route list, indicating a match)

} <Switch> {/* To add exact to root routes, */} <Route exact path="/" Component ={HomePage} /> <Route path="/user" component={UserPage} /> <Route component={EmptyPage} /> </Switch> class EmptyPage extends Component { render() { return ( <div> <h3>404</h3> </div> ); }}Copy the code

1.PureComponent shallow comparison (only one state is compared, multiple states are invalid)

import React, { Component, PureComponent } from "react"; export default class PureComponentPage extends PureComponent { constructor(props) { super(props); this.state = { counter: 0 }; } setCounter = () => { this.setState({ counter: 100 }); }; // shouldComponentUpdate(nextProps, nextState) {// shouldComponentUpdate(nextProps, nextState) {// Return nextstate.count! == this.state.count; // } render() { const { counter, obj } = this.state; return ( <div> <h1>PuerComponentPage</h1> <div onClick={this.setCounter}>counter: {counter}</div> </div> ); }}Copy the code