React has been used for a long time. Do you find that you still don’t understand the React implementation principle? Don’t understand React internal procedures? This series of articles is based on React V16.8.6 and features 2-3 highlights per week, each of which is a key point in React. Comments are welcome.

React Export objects

Direct copy of the code, comments on the code


var React = {

  / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the Children deal with -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  // The utility function associated with props. Children
  // props. Children is not a strict array, so array-like tools are added
  Children: {

    / / similar array. The map
    map: mapChildren,

    / / similar array. ForEach
    forEach: forEachChildren,

    // Count the number of prop.children, count the number of direct children
    // Children is either an array or a separate react.element
    Array.isArray(children) is true
    // Children is undefined when the number of children is 0
    count: countChildren,

    // Turn children into an array
    // children becomes an empty array for undefined
    // Change a single element into an array with only one element
    // Convert children from an array to an array. The difference is the key of each element in the array. ToArray is the identifying key of.0
    toArray: toArray,

    If there is only one direct child node, it is returned
    Children. Only expected to receive a single React element child.
    only: onlyChild
  },
  // ---------------------------------------------------------------

  // ------------------------- Component -----------------------------
  Return {current: null};
  
       where r = react.createref ()
  createRef: createRef,

  // React.Com
  // It is a constructor and defines some methods on its prototype
  // isReactComponent
  // setState
  // forceUpdate
  Component: Component,

  // Inherits from Component, which is also a constructor
  // Its prototype has a property isPureReactComponent = true
  PureComponent: PureComponent,
  // ------------------------------------------------------------------

  // React cross-component data transfer scheme to avoid unnecessary trouble for intermediate elements to pass props
  Context provides a way to share such values between components without explicitly passing props layer by layer through the component tree.
  createContext: createContext,
  
  // Create a React component that can forward the ref attribute it receives to another component in its component tree
  // react. forwardRef accepts the render function as an argument.
  React will call this function with props and ref as arguments. This function should return the React node.
  forwardRef: forwardRef,
  
  / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- performance optimization -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  In Suspense, load components asynchronously to reduce the volume of packages loaded for the first time
  // Returns a component loaded asynchronously
  lazy: lazy,
  
  // Optimize the performance of functional components
  // Similar to PureComponent, render the following component and no matter how you change the param object, it will not render again
  // const Test = React.memo(
  // (props) => <div>{props.param.count}</div>,
  // (prevProps, nextProps) => true)
  memo: memo,
  // ---------------------------------------------------------------
  
  error: error,
  warn: warn,

  / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the React hooks series -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  // hooks allow you to use state and other React features without writing a class

  // Similar to setState
  // const [a, setA] = useState(aInitialValue) // aInitialValue a
  // a is the latest value after each setA execution. SetA is similar to this.setState, and the argument can be a function or something else
  useState: useState,
  
  // Receive a function that contains imperative code with possible side effects.
  // The function assigned to useEffect is executed after the component is rendered to the screen,
  UseEffect can be used to change the DOM, add subscriptions, set timers, log, and perform other side effects
  UseEffect returns a cleanup function that is executed before rerender each time. The cleanup timer and unsubscribe times can be added to the return function
  // const r = useRef()
  // useEffect(() => {
  // r.current = setTimeout(xx, 1000);
  // return () => { clearTimeout(r.current) }
  / /})
  useEffect: useEffect,
  
  // const [state, dispatch] = useReducer(reducer, initialArg, init);
  // It receives a reducer of the form (state, action) => newState,
  // Returns the current state and its accompanying dispatch method
  useReducer: useReducer,
  
  // useRef returns a {current: null} Object processed by Object.seal, that is, the key property of the Object cannot be changed
  
      
// Can also be used to store values // const r = useRef(), r.rent = setTimeout(xx, 1000), clearTimeout(r.rent) useRef: useRef, / / -- -- -- -- -- -- -- -- -- -- -- -- the function component performance optimization tools -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - // Returns a cached function, which is regenerated only when variables in the array change. This can be used to avoid rerendering of subcomponents and improve performance // return the function defined by itself, lazy execution useCallback: useCallback, // Lazy evaluation, which recalculates the memoized value only when a dependency changes and returns the self-defined value useMemo: useMemo, // ------------------------------------------------------------- // Use useContext(MyContext) in the function Component to get the value of the nearest Provider // No Consumer is required useContext: useContext, // allows you to customize the instance value exposed to the parent component when using the refs, in conjunction with the forwardRef // function FancyInput(props, ref) { // const inputRef = useRef(); // useImperativeHandle(ref, () => ({ // focus: () => { // inputRef.current.focus(); / /} / /})); // return ; / /} // FancyInput = forwardRef(FancyInput); useImperativeHandle: useImperativeHandle, // A tag that can be used to display custom hooks in React developer tools useDebugValue: useDebugValue, // Its function signature is the same as useEffect, but it calls effect synchronously after all DOM changes // function useLayoutEffect(effect: EffectCallback, inputs? : InputIdentityList): void; // function useEffect(effect: EffectCallback, inputs? : InputIdentityList): void; useLayoutEffect: useLayoutEffect, // ------------------------------------------------------------ // Symbol(react.fragment), which allows you to group sublists without adding extra nodes to the DOM Fragment: REACT_FRAGMENT_TYPE, // Symbol. For ('react. Profiler ') React performance correlation Profiler: REACT_PROFILER_TYPE, StrictMode does not render any visible UI, // is a tool for highlighting potential problems in applications, checking for outdated apis, identifying unsafe life cycles, and detecting unexpected side effects StrictMode: REACT_STRICT_MODE_TYPE, // Implement lazy loading with lazy // You can specify loading indicators in case some child components in its component tree are not yet ready to render // const OtherComponent = React.lazy(() => import('./OtherComponent')); // <Suspense fallback={<Spinner />}><OtherComponent /></Suspense> Suspense: REACT_SUSPENSE_TYPE, // ------------------------- Element ------------------------------------- // createElement(type, config, children) // Create a new element based on type. React uses this function a lot. JSX converts it to this function // <Page ref={r} name="lxfriday" key="1">{childen}</Page> / / {? typeof: Symbol(react.element), key:"1",props:{name:"lxfriday",children:{... }},ref:null} createElement: createElementWithValidation, // cloneElement(element, config, children) // Clone the React element and return the new React element // The props of the element is the result of combining the new props with the props of the original element. The new child element replaces the existing child element, and the key and ref from the original element are retained. // react.cloneElement () is almost the same as: {children} cloneElement: cloneElementWithValidation, // There are two core statements: // var validatedFactory = createElementWithValidation.bind(null, type); // validatedFactory.type = type; // Use createElement instead createFactory: createFactoryWithValidation, // Verify that the object is a React element and return true or false isValidElement: isValidElement, // Export the React version version: ReactVersion, unstable_ConcurrentMode: REACT_CONCURRENT_MODE_TYPE, __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: ReactSharedInternals }; Copy the code

React FAQs

Why does React have to be imported into code that contains JSX

Let’s look at the pre-compile code

<div ref={r}>
  <span>1</span>
</div>
Copy the code

Babel compiled code

React.createElement("div", {
  ref: r
}, React.createElement("span".null."1"));
Copy the code

JSX uses the React. CreateElement to create the Render tree, so the React import is required.

Why should function defined in class-Component be bound to this

Here are three possible scenarios

  • handleClickWithout binding this, printundefinedThe reason is that handleClick is assigned to onClick by way of an assignment, so the default this will fail, similar to thisdisplay = foo.display; display();This is not a foo
  • handleBindClick1Bind this with the arrow function, and its this will not be changed, and print TestThis
  • handleBindClick2Bind (this) to the context and print TestThis
class TestThis extends Component {
  handleBindClick1 = (a)= > {
    console.log('handleBindClick1'.this);
  }
  handleClick() {
    console.log('handleClick'.this);
  }
  handleBindClick2() {
   console.log('handleBindClick2'.this); 
  }
  render() {
    return (
      <div>
        <button onClick={this.handleClick}>click not bind </button>
        <button onClick={this.handleBindClick1}>bind 1 click</button>
        <button onClick={this.handleBindClick2.bind(this)}>bind 2 click</button>
      </div>); }}Copy the code

How many forms does ref take

function ref

<Page ref={r => this.page = r}>xxx</Page>
Copy the code

object ref

const r = useRef(); // r = {current: null}
<Page ref={r}>xxx</Page>
Copy the code

String ref (not recommended)

<Page ref="page">xxx</Page>

this.refs.page.xxx
Copy the code