React implements automatic reporting of PV/Click buried point Hooks

Custom hooks is an extension based on React Hooks. We can formulate combined hooks that meet business needs according to business needs, and pay more attention to logical units. How to encapsulate a piece of logic and achieve reuse is the original intention of custom hooks.

Custom hooks can also be said to be the aggregation product of React Hooks, which consists of one or more React Hooks to solve some complex logic.

A traditional custom hook looks like this:

function useXXX(参数A, 参数B, ...) {
  /* 
    实现自定义 hooks 逻辑
    内部应用了其他 React Hooks
  */
  return [xxx, ...]
}

use:

const [xxx, ...] = useXXX(参数A, 参数B, ...)

Custom hooks  parameters  may be the following:

  • hooks initialization value

  • Callback functions for some side effects or events

  • Can be   the element or component instance useRef obtained DOM

  • no parameters required

The return value of  custom hooks   may be the following:

  • Responsible for rendering the state obtained by the view

  • update function component method, essentially  useState either useReducer

  • Some state passed to descendant components

  • no return value

 characteristic

First of all, we need to understand that the custom hooks written by developers are essentially functions and are executed in function components. Custom hooks driver is essentially the execution of function components .

driving conditions

There are two main driving conditions for custom hooks: 

  1. props Changes brought about by function component execution.

  2. useState Or  useReducer change  state causes an update of the function component.

 

 sequence principle

There must be at least one React Hooks inside the custom hooks, so the custom hooks must also follow the rules of React Hooks, they cannot be placed in conditional statements, and the consistency of execution order must be maintained.  Why is this?

This is because during the update process, if the hooks are added or deleted through the if conditional statement, then in the process of reusing the hooks, the state of the reusable hooks will be inconsistent with the current hooks. Therefore, we must pay attention to the consistency of the order of hooks during development.

 practice

Next, let's implement a  custom hooks that can automatically report page views | click time  --  useLog.

Through this custom hooks, you can  control the monitoring of DOM elements and distinguish dependencies .

Write custom hooks:

export const LogContext = createContext({});

export const useLog = () => {
  /* 定义一些公共参数 */
  const message = useContext(LogContext);
  const listenDOM = useRef(null);

  /* 分清依赖关系 */
  const reportMessage = useCallback(
    function (data, type) {
      if (type === "pv") {
        // 页面浏览量上报
        console.log("组件 pv 上报", message);
      } else if (type === "click") {
        // 点击上报
        console.log("组件 click 上报", message, data);
      }
    },
    [message]
  );

  useEffect(() => {
    const handleClick = function (e) {
      reportMessage(e.target, "click");
    };
    if (listenDOM.current) {
      listenDOM.current.addEventListener("click", handleClick);
    }

    return function () {
      listenDOM.current &&
        listenDOM.current.removeEventListener("click", handleClick);
    };
  }, [reportMessage]);

  return [listenDOM, reportMessage];
};

In the above code, the following 4 React Hooks are used:

  • Use  useContext the public information of the buried point, and when the public information changes, it will be updated uniformly.

  • Use  useRef to get the DOM element.

  • Use  useCallback the cache report information  reportMessage method to get the content inside  useContext . As  context a dependency, when the dependency changes,  reportMessage the function is redeclared.

  • Use  useEffect listener DOM event, use it  reportMessage as a dependency,  useEffect perform event binding in it, and return the destroy function for unbinding.

Dependency : context change -> let  the context imported  reportMessage redeclaration -> let the binding DOM event listener  useEffect be able to bind the latest reportMessage 

Use custom hooks:

import React, { useState } from "react";
import { LogContext, useLog } from "./hooks/useLog";

const Home = () => {
  const [dom, reportMessage] = useLog();
  return (
    <div>
      {/* 监听内部点击 */}
      <div ref={dom}>
        <button> 按钮 1 (内部点击) </button>
        <button> 按钮 2 (内部点击) </button>
        <button> 按钮 3 (内部点击) </button>
      </div>
      {/* 外部点击 */}
      <button
        onClick={() => {
          console.log(reportMessage);
        }}
      >
        外部点击
      </button>
    </div>
  );
};
// 阻断 useState 的更新效应
const Index = React.memo(Home);

const App = () => {
  const [value, setValue] = useState({});
  return (
    <LogContext.Provider value={value}>
      <Index />
      <button onClick={() => setValue({ cat: "小猫", color: "棕色" })}>
        点击
      </button>
    </LogContext.Provider>
  );
};

export default App;

As above, when  context a change occurs, the effect of normal reporting can be achieved. Small details: Use  React.memo to block  the update effect of App component changes  state on  Home components.

result

At the beginning, click the buttons 1, 2, and 3 in sequence, and the effect is as follows:

After clicking the button, and then clicking buttons 1, 2, and 3 in sequence, the effect is as follows:

 

 

Guess you like

Origin blog.csdn.net/weixin_46600931/article/details/128777323