background

1. React Series

Firstly, I would like to introduce the background. I have been writing VUE from the beginning of the internship until March 2021.3. After the new nest, react is mainly used, of course, VUE is also used, partial H5 end.

From the beginning, react series, will learn to write, from basic -> hooks -> source code -> interview questions, etc., will also write some of their own transformation process.

Related code will be in the following πŸ‘‡πŸ» warehouse, for a start.

  • Warehouse: React – TypeScript
  • Online preview: Junjie React Learning system

Personal blogs

First personal blog, personal learning of all notes, as well as a variety of front-end resources to share, interested brother can see, handystartA little. If you want to build a blog like this, there are tutorials, free from start to finish. There is an official account in the blog, welcome everyone together, learn to punch in every day, and make progress together!

1. Life cycle

React life cycle diagram

I have this picture imprinted in my mind, so I draw my own pictures and spread some thoughts in the middle. U1s1, do not know react lifecycle name why how long ~~~, small program, VUE are relatively short. After all, it’s very frequent, except for Hooks.

1, the constructor

Constructor is a generic constructor for a class, often used for initialization, that is part of the lifecycle. Later versions of React also leave class components unwritten.

Note: When used in constructors, the super keyword appears alone and must be used before the this keyword. The super keyword can also be used to call functions on the parent object. MDN instructions

class JJTest extends React.Component {
  / / constructor notation
  constructor(props) {
    super(props);
    this.state = {
      count: 0};this.handleClick = this.handleClick.bind(this);
  }
  // Declare directly
  state = {
    count: 0}; }Copy the code

2, getDerivedStateFromProps

Trigger timing: state change, props change, forceUpdate, as shown above.

This is a static method, a role that is “unrelated” to the component itself. In this static method, you cannot access data on any component except for the two default positional arguments, nextProps and currentState.

// Called during initialization/update
static getDerivedStateFromProps(nextProps, currentState) {
  console.log(nextProps, currentState, "GetDerivedStateFromProps");
  // The return value is a change to currentState
  return {
    fatherText: nextProps.text,
  };
}
Copy the code

3, render

The JSX structure returned by the render function, which describes the specific render content. When render is called, it checks for changes to this.props and this.state and returns one of the following types:

  • The React elements. Usually created through JSX. For example,
    React will be rendered as DOM nodes, and React will be rendered as custom components, either

    They’re all React elements.

  • An array or fragments could. Enable the render method to return multiple elements. For more details, see the Fragments documentation.
  • Portals. You can render child nodes into different DOM subtrees. For more details, see the documentation on Portals
  • It is a string or a number. They are rendered as text nodes in the DOM
  • Boolean type or NULL. Nothing is rendered. (This is primarily used to support patterns that return test &&, where test is a Boolean type.)

Note: If shouldComponentUpdate() returns false, render() is not called.

Hooks do not need to write render functions. Pay attention to the point is that even if the Hooks don’t need to write a render, don’t use the React. XXX, components inside still have to import the React from “React”; (as for the reasons, I will follow it in depth, you can also explain). React officials have also stated that this will be removed in future versions.

4, componentDidMount

It is used to perform certain operations when the component is loaded, such as initiating network requests or binding events. Mounted vue mounted vue mounted vue mounted

SetState () is called directly in componentDidMount(). It will trigger extra render, which is two render times, but that’s not a big deal, it’s still understandable.

5, shouldComponentUpdate

This method determines whether a new render needs to be triggered by returning true or false. Since rendering triggers the last level, it’s also where performance optimization is important. Prevent unnecessary rendering by adding criteria. Note: This method is not called for the first rendering or when forceUpdate() is used.

React officially offers a common optimization called PureComponent. The core principle of PureComponent is that it implements a function shouldComponentUpdate by default. This function makes a shallow comparison between props and state to determine whether an update is fired.

Of course, PureComponent has its drawbacks. Be careful when using PureComponent: Because of the shallow comparison, the page may not be updated because of the inconsistencies in the deep data. Not suitable for use in state and Prop with multiple layers of nested objects.

shouldComponentUpdate(nextProps, nextState) {
  // A shallow comparison only compares the value and reference, and does not compare every value in an Object
  if (shadowEqual(nextProps, this.props) || shadowEqual(nextState, this.state) ) {
    return true
  }
  return false
}
Copy the code

6, getSnapshotBeforeUpdate

Is called before a DOM update and returns as the third parameter to componentDidUpdate.

getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log("GetSnapshotBeforeUpdate method execution");

    return "The third parameter of componentDidUpdated";
}
Copy the code

7, componentDidUpdate

This method is not executed for the first render. You can use setState, which triggers rerendering, but be careful to avoid an infinite loop

 componentDidUpdate(preProps, preState, valueFromSnapshot) {
    console.log("ComponentDidUpdate method execution");

    console.log("The value you get from getSnapshotBeforeUpdate is", valueFromSnapshot);
  }
Copy the code

8 componentWillUnmount.

It is used to unbind some events and clear resources, such as canceling timers and unsubscribeing events

summary

The lifecycle has to be understood, has to be written, and has to see the results of the lifecycle execution in each case. All of this code is available in the React-typescript repository and can be cloned to run around or accessed directly at LifeCycle. There are other lifecycles, such as componentDidCatch, UNSAFE_componentWillMount(), and so on, just to give you a quick idea.

Second, the JSX

1. Loop lists

JSX uses map to render the list loop class. Vue uses V-for in template

{
  list.map((item, index) = > {
    return <AppCard key={index} title={item.title} onClick={item.onClick} />;
  });
}
Copy the code

2, style,

(1)className

It is possible to write a single class; dynamic concatenation requires the classNames library

import style from './style.css'

<div className={style.class1 style.class2}</div>
Copy the code

(2)style

Note: The two parentheses (the style is resolved as an object), similar to the -join style attribute, need to be converted into a small hump.

<div style={{ marginTop: 8}} > style < / div >Copy the code

(3) the CSS isolation

U1s1, CSS isolation block or vUE scoped easy to use

  • css-module

    Create-react-app has built-in configuration that uses CSS Modules. Similar to Vue scoped, it hashed the generated class

// style.module.css
.text {
    color: blue
}
// app.tsx
import s from "./style.module.css";
class App extends Component {
  render() {
    return <div className={s.text}>css-module text</div>; }}/ / the compiled
.text_3FI3s6uz {
    color: blue;
}
Copy the code
  • styled-components

    At present, the community’s most popular CSS in JS scheme, personal feeling a little awkward, do not like

/ / introduce styled - components
import styled from "styled-components";

// Change div style
const Title = styled.div` font-size: 30px; color: red; `;
class App extends Component {
  render() {
    return (
      <>
        <Title>CSS in JS solution</Title>
      </>); }}Copy the code

3、一δΈͺ JSX

At the beginning of the vUE turn over will be some not adapt to (how many people write JSX directly in vUE), before the use of vUE Sfc writing, of course, write more familiar with. As for the pros and cons of JSX for React, the comments section is full of opinions.

The code corresponds to the page preview

render() {
    return (
      <>
        <Alert title="The console shows the process of the parent-child component lifecycle." />
        <div className="fatherContainer">
          <Button onClick={this.changeText} type="primary">Modify the text content of the parent component</Button>
          <Button onClick={this.hideChild} type="danger">{this.state.hideChild ? "Show" : "hide "} child components</Button>
          {this.state.hideChild ? null : (
            <LifeCycle text={this.state.text} count={1} />
          )}
        </div>
        <div>
          <BlockLoading loading={this.state.loading} iconSize={64} />
          <iframe
            src={this.state.lifeCycle}
            title="navigation"
            width="100%"
            height="600px"
            onLoad={this.onLoading}
            onError={this.onLoading}
          ></iframe>
        </div>
      </>
    );
  }
Copy the code

Third, basic components

For components, the difference between personal feeling and VUE is relatively large, and the granularity is more detailed, of course, it also increases certain difficulty. Here is a simple example of a TS version of the title component with an Icon

import cn from "classnames";
import React from "react";
import "./style/index.less";
import { Icon,IIconProps } from "zent";

interface IProps {
  title: string; iconType? : IIconProps['type']; isShowIcon? : boolean; iconClassName? : string; titleClassName? : string; }export const ContentTitle: React.FC<IProps> = (props) = > {
  const { title, iconType = 'youzan', isShowIcon = false, iconClassName, titleClassName, ... popProps } = props;return (
    <div className={cn("content-title", titleClassName)} >
      {title}
      {isShowIcon && <Icon
        className={cn("content-title__icon", iconClassName)}
        {. popProps}
        type={iconType}
      />}
    </div>
  );
};

export default ContentTitle;

Copy the code

4. Advanced component HOC

1, meaning

Same as Vue Mixins, both are designed to solve the problem of code reuse, but Mixins have been abandoned in React and are not recommended in VUE either. The main disadvantages are naming conflict, interdependence, inconvenient maintenance and so on.

Higher order components are functions that handle react components. They are similar to export/import in ES6, except that the higher order components are processed and exported. Similar to the equation: y = ax + b, x is the entry (component), which is calculated against a and B, and the final Y (processed component) is given to you.

2, the Demo

Official website implementation Demo: high-level components

A simple high-level component (implemented in two ways: property broker and reverse inheritance) :

// Property broker: modifications to component properties
const JJHOC = (WrappedComponent) = > {
  return class NewComponent extends React.Component {
    render() {
      const newProps = { type: "HOC" };
      return <WrappedComponent {. this.props} {. newProps} / >; }}; };// Reverse inheritance: return the super.render() method in the render() method
const JJHOC = (WrappedComponent) = > {
  return class NewComponent extends WrappedComponent {
    render() {
      return super.render(); }}; };Copy the code

3, Use HOC

  • React-router withRouter: Obtain history, routing information
  • Redux Connect Connects the React component to the Redux Store and mounts the Dispatch method to the component.

V. Component communication

1, props,

Unlike vue, react props can be passed directly. Mount function on props. This is equivalent to vue’s $emit. It is also important to note that child components cannot change the props value

import React from "react";

function Child(props) {
  const sendMsg = (msg) = > {
    props.onClick("Messages for child components");
  };
  return (
    <div>
      <div>Child component title: {props. Title}</div>
      <button onClick={()= >SendMsg (" child component message ")}> Child to parent</button>
    </div>
  );
}

function Father() {
  const onClick = (msg) = > {
    console.log('Parent component receives:${msg}`);
  };
  return (
    <div>
      <Child title="Component props test" onClick={onClick}></Child>
    </div>
  );
}

export default Father;
Copy the code

2, the context

The React Context website explains that values are passed across components. A context is created, and components within the context can use data with value through the Provider

import * as React from "react";
import { Button } from "zent";
// Context allows us to pass values deep into the component tree without explicitly passing them through each component.
// Create a context for the current theme (" primary "is the default).
const ThemeContext = React.createContext("primary");
export default class App extends React.Component {
  render() {
    // Use a Provider to pass the current theme to the following component tree.
    // This value can be read by any component, no matter how deep.
    // In this example, we pass Danger as the current value.
    return (
      <ThemeContext.Provider value="danger">
        <Toolbar />
      </ThemeContext.Provider>); }}// The middle component no longer has to specify to pass theme down.
function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  // contextType reads the current theme context.
  // React will look up to the nearest theme Provider and use its value.
  // In this example, the current theme value is "danger".
  static contextType = ThemeContext;
  render() {
    return <Button type={this.context}>The context test</Button>; }}Copy the code

3, Redux

Redux Chinese documents

The three core elements of Redux:

  • Action: An action can be said to be an action that describes the event to be fired.
  • State: a single data source to store our data.
  • Reducer: Changes the state value by triggering the action event.

You don’t have to, many project contexts are sufficient

(1) Mount

Create a store using createStore and place it in the container component through the Provider

// index.js
const store = createStore(appReducer);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>.document.getElementById("root"); ;Copy the code

(2) Create the method of modification

Similar to VUEX, action is used to modify data

// action.js
export const addConst = (payload) = > {
  type: "ADD_CONST",}export const minusConst = (payload) = > {
 type: "MINUS_CONST",}Copy the code

(3) Create a store collection

When dispatch triggers the corresponding method, the corresponding operation is performed to modify the store data.

// appReducer.js
const initialState = { count: 0 };
const reducer = (state = initialState, action) = > {
  switch (action.type) {
    case "ADD_CONST":
      return { count: count + 1 };
    case "MINUS_CONST":
      return { count: count - 1 };
    default:
      returnstate; }};export default reducer;
Copy the code

(4) Redux use posture in the component

import React from "react";
import { connect } from "react-redux";

const ReduxDemo: React.FC = (props) = > {
  const addCount = () = > {
    const { dispatch } = props;
    dispatch({
      type: "ADD_CONST"}); };const minusCount = () = > {
    const { dispatch } = props;
    dispatch({
      type: "MINUS_CONST"}); };return (
    <div>
      <button onClick={addCount}>add</button>
      <button onClick={minusCount}>Reduction of</button>
      <div>{props.state}</div>
    </div>
  );
};

const mapStateToProps = (state) = > {
  return {
    count: state.count,
  };
};
export default connect(mapStateToProps)(ReduxDemo);
Copy the code

Vi. Component verification

React props are not required to declare them, but if your project becomes standardized, you will need to declare them in your PropTypes

Nowadays, however, types are more often validated with typescript, and problems can be discovered during development.

import * as React from "react";
import PropTypes from "prop-types";

interface IProps {
  name: string;
}

const PropsDemo: React.FC<IProps> = ({ name }) = > {
  return <h1>Hello, {name}</h1>;
};

PropsDemo.propTypes = {
  name: PropTypes.string,
};
Copy the code

Seven, the React to the Router

  • React Router website English version
  • React Router Chinese document is not very clear

1, pay attention to

  • React-router: Implements the react-router core function. The react-router version 3. X also includes a method to manipulate the DOM.
  • React-router-dom: React-router-dom is based on the React-router and adds some browser functionality. For example, the Link component renders an A tag, and the Link component source a tag line. The BrowserRouter and HashRouter components, the former using pushState and popState events to build routes, and the latter using window.location.hash and HashChange events to build routes.
  • React-router-native: Based on the React-router, it is similar to the React-router-dom and adds functionality to the React-Native operating environment

2、一δΈͺ Demo

import React, { Component } from "react";
import Admin from "./pages/admin/admin";
import Login from "./pages/login/Login";
import { HashRouter, Route, Switch } from "react-router-dom";
class App extends Component {
  render() {
    return (
      <HashRouter>
        <Switch>
          <Route path="/" component={Admin}></Route>
          <Route path="/login" component={Login}></Route>
        </Switch>
      </HashRouter>); }}export default App;
Copy the code

3. Route transmission parameters

(1) the params

// router
<Route path='/path/:id' component={Path}/>
/ / the refs
<link to="/path/789">xxx</Link>
this.props.history.push({pathname:`/path/${id}`});
/ / to get
this.props.match.params.id
Copy the code

(2) the query

// router
<Route path='/query' component={Query}/>
/ / the refs
<Link to={{ path : '/query',query : { id : '789' }}}>xxx</Link>

this.props.history.push({pathname:"/query".query: { id : '789' }});
/ / to get
this.props.location.query.id
Copy the code

(3) the Hooks

/ / jump
let history = useHistory();
history.push("/");

/ / to get
useLocation();
useParams();
useRouteMatch();
Copy the code

4. Exact attribute

Exact is an attribute under Route. Generally, react routes match all matched Route groups. Exact makes Route matching more stringent.

The value of exact is bool. True indicates strict matching. False indicates normal matching.

When exact is true, ‘/link’ and ‘/’ do not match, but when false they do.

Eight, summary

After learning the life cycle, practicing JSX more, and writing more components with React Router and Redux, you will be able to get started in development. There are not too many apis to learn and it is relatively free to write. Although React has a strong ecology and many choices, this raises the question: What are the React best practices?

Finally, recommend some learning resources, everybody work together!

  • Vue to React does not completely refer to the north before writing an article, the overall comparison of Vue and React
  • Here’s a problem with React’s design idea: Why doesn’t React offer some API like Vue?
  • React technology stack series tutorial ruan Da React tutorial ecology, a little bit old
  • React Introduction example tutorial ruan Yifeng products must be high-quality products!
  • Nuggets React Hot there are a lot of big names to pick from
  • React development must know 34 skills related to the skills, you can contact the play basic section to try
  • The evolution from Mixin to HOC to Hook code reuse

reference

  • React Chinese Documents
  • Redux Chinese documents
  • React Router website English version
  • Introduction to React Advanced Component (HOC) πŸ“– and practices πŸ’»
  • Simple use of react-Redux
  • React route parameters and their differences