directory

  • preface
  • React.useRef
  • React.createContext/useContext
  • conclusion

One, foreword

In the previous article, we learned that the value of a variable in React state will be equal to the new value whenever the value of the variable changes and is updated once.

So how can we use and change a variable throughout React like Vue?

Yes, these are useRef and useContext

Second, the React. UseRef

Const n=React. UseRef (initial value)

How to express the value of n: n. rent

A change in the value of useRef does not trigger a UI update. The value of useRef is valid only for the current component, through the current component until the component dies.

1. Use React. UseRef

const App = () = > {
  /* Define a Ref variable n */
  const n = React.useRef(0);
  const log = () = > {
    setTimeout(() = > {
      /* use n.rent to indicate the current value of n */
      console.log("n:", n.current);
    }, 3000);
  };
  return (
    <div>N :{n.rent} /* does not trigger an update */<button onClick={log}>log</button>
      <hr />
      <button
        onClick={()= > {
          n.current += 1;
        }}
      >
        n+1
      </button>
    </div>
  );
};
ReactDOM.render(<App />.document.getElementById("root"));
Copy the code
  • Results show
    • Whether I hit log and then n plus 3, or I hit n plus 3 and then log. It prints a 3, and the reason is becauseUseRef has only one variable value throughout and does not extend out of n as state does

2. UI updates are automatically triggered when the useRef value changes

We know that when the value of useState in React changes, the UI re-render is automatically triggered. Can we just take the idea of updating the state value and re-render it so that the useRef value is updated at this time?

const App = () = > {
  const n = React.useRef(0);
  const update = React.useState(null) [1]; /* We just need the setX function */
  const log = () = > {
    setTimeout(() = > {
      console.log("n:", n.current);
    }, 3000);
  };
  return (
    <div>
      n:{n.current}
      <button onClick={log}>log</button>
      <hr />
      <button
        onClick={()= >{ n.current += 1; /* Retrigger page rendering whenever the value in useState changes */ update(n.rent); }} > n+1</button>
    </div>
  );
};
ReactDOM.render(<App />.document.getElementById("root"));
Copy the code
  • Results show
    • This, combined with the setX function in useState, causes the useRef value to change at the same time that the page automatically rerenders and displays the updated useRef value.

Third, the React. CreateContext/useContext

Create a context object. When React renders a component that subscribes to the Context object, it reads the current Context value from the closest matching Provider above it in the tree. Use the defaultValue parameter only if the component has no matching provider at the top of the tree. This is helpful for isolating test components without wrapping them.

Note: Passing undefined as a Provider value does not cause a component to use defaultValue.

The context object is more like a block-level scope in which components can use JS variables and objects from the upper-level and upper-level context objects.

1, use the React. CreateContext/useContext

Start by creating a context object, globalText. Then create a “block-level scope”. Write a JS variable or object to be passed in the Provider’s value property.

const globalText = React.createContext(null);
const App = () = > {
  const [n, setN] = React.useState(0);
  const [m, setM] = React.useState(0);
  return (
    /* Wrapped by GlobalText.provider is equivalent to a block-level scope */
    <globalText.Provider value={{ n.setN.m.setM}} >
      <div className="wrapper">
        <div>n:{n}</div>
        <div>m:{m}</div>
        <ChildA />
        <ChildB />
      </div>
    </globalText.Provider>
  );
};
const ChildA = () = > {
  /* Destruct assignment: object matching */
  const { n, setN } = React.useContext(globalText);
  return (
    <div>
      <button
        onClick={()= > {
          setN(n + 1);
        }}
      >
        ChildA:n+1
      </button>
    </div>
  );
};
const ChildB = () = > {
  const { m, setM } = React.useContext(globalText);
  return (
    <div>
      <button
        onClick={()= > {
          setM(m + 1);
        }}
      >
        ChildB:m+1
      </button>
    </div>
  );
};
ReactDOM.render(<App />.document.getElementById("root"));
Copy the code
  • Results show
    • As you can see, we can modify n and m directly in the ChildA and ChildB components using the setN and setM functions of the uppermost component.

Four,

  • The react. useRef is used to declare variables that have one and only one value (as opposed to useState) and run through the current component until it dies

  • The React. CreateContext/useContext is to create a context object, is a “block level scope”. In this “block-level scope”, the JS variables and objects provided by the Context can be used throughout the Context object (block-level scope), and the components within the Context and all nested components within the Context can use the JS variables and objects provided by the Context, etc.