reactjs - उपयोग कब करें




(2)

useImperativeHandle

कल्पना कीजिए कि आप एक घटक Table बनाते हैं। आप यह निर्दिष्ट करना चाह सकते हैं कि Table पर उस घटक के साथ बातचीत कैसे होती है; यह हो सकता है कि, उदाहरण के लिए, आप केवल मूल तत्व तक पहुंचने में सक्षम होने के बजाय एक विशेष सेल प्रदान करना चाहते हैं।

[index.tsx]

import React, { useRef, useEffect } from "react";
import { render } from "react-dom";
import Table from "./Table";

import "./styles.css";

function App() {
  const tableRef = useRef(null);

  useEffect(() => {
    tableRef.current.style.color = "green";
  }, []);

  return (
    <div>
      <Table ref={tableRef} />
    </div>
  );
}

const rootElement = document.getElementById("root");
render(<App />, rootElement);

[Table.tsx]

import React, { useRef, useImperativeHandle, forwardRef } from "react";

function Table(props, ref) {
  const cellRef = useRef(null);
  useImperativeHandle(ref, () => cellRef.current);

  return (
    <table>
      <tr>
        <td>First</td>
        <td ref={cellRef}>Second</td>
      </tr>
    </table>
  );
}

export default forwardRef(Table);

यहां उपलब्ध है।

useLayoutEffect

यह उपयोग के रूप में ही है, लेकिन सभी DOM म्यूटेशन पूरा होने के बाद ही फायर होते हैं। केंट सी। डोड्स का यह लेख इन दोनों के बारे में किसी और के साथ-साथ अंतर को भी बताता है, वे कहते हैं:

समय का 99% [ useEffect ] वह है जो आप उपयोग करना चाहते हैं।

मैंने ऐसा कोई उदाहरण नहीं देखा है जो इसका विशेष रूप से वर्णन करता हो, और मुझे यकीन नहीं है कि मैं कुछ भी बना पाऊंगा। यह कहना शायद सबसे अच्छा है कि आपको केवल तभी उपयोग करना चाहिए जब उपयोग में कोई समस्या हो।

useDebugValue

मुझे ऐसा लगता है कि डॉक्स इसे समझाने का एक बहुत अच्छा उदाहरण है। यदि आपके पास एक कस्टम हुक है, और आप इसे रिएक्ट DevTools के भीतर लेबल करना चाहते हैं, तो यह वही है जो आप उपयोग करते हैं।

यदि आपके पास इसके साथ कोई विशिष्ट समस्या है, तो संभवत: यह टिप्पणी करना या किसी अन्य प्रश्न को पूछना सबसे अच्छा होगा, क्योंकि मुझे लगता है कि कुछ भी लोग यहां डाल देंगे, बस डॉक्स को दोहरा रहे हैं, कम से कम जब तक हम एक अधिक विशिष्ट समस्या तक नहीं पहुंचते।

मुझे समझ में नहीं आ रहा है कि निम्न उपयोग IImperativeHandle, useLayoutEffect और useDebugValue हुक की आवश्यकता क्यों है, क्या आप उदाहरण दे सकते हैं जब उनका उपयोग किया जा सकता है, लेकिन प्रलेखन से उदाहरण नहीं।


मुझे इस उत्तर को यह कहते हुए प्रस्तुत करने की अनुमति दें कि ये सभी हुक बहुत कम उपयोग किए जाते हैं। 99% समय, आपको इन की आवश्यकता नहीं होगी। वे केवल कुछ दुर्लभ कोने-केस परिदृश्यों को कवर करने के लिए हैं।

useImperativeHandle

आमतौर पर जब आप उपयोग करते हैं, तो आपको उस घटक का उदाहरण मूल्य दिया जाता है जिसे ref संलग्न करता है। यह आपको DOM तत्व के साथ सीधे इंटरैक्ट करने की अनुमति देता है।

useImperativeHandle बहुत समान है, लेकिन यह आपको दो काम करने देता है:

  1. यह आपको लौटाए गए मूल्य पर नियंत्रण देता है। उदाहरण तत्व को वापस करने के बजाय, आप स्पष्ट रूप से बताते हैं कि वापसी मूल्य क्या होगा (नीचे स्निपेट देखें)।
  2. यह आपको अपने स्वयं के कार्यों के साथ मूल कार्यों (जैसे blur , focus , आदि) को बदलने की अनुमति देता है, इस प्रकार सामान्य व्यवहार या पूरी तरह से एक अलग व्यवहार के दुष्प्रभाव की अनुमति देता है। हालाँकि, आप जो चाहें उसे फंक्शन कह सकते हैं।

कई कारण हो सकते हैं जो आप उपरोक्त में से किसी एक को करना चाहते हैं; हो सकता है कि आप मूल गुणों को मूल में प्रकट नहीं करना चाहते हों या हो सकता है कि आप मूल कार्य के व्यवहार को बदलना चाहते हों। कई कारण हो सकते हैं। हालाँकि, useImperativeHandle का उपयोग शायद ही कभी किया जाता है।

useImperativeHandle ref का उपयोग करते समय मूल घटक के संपर्क में आने वाले उदाहरण मान को अनुकूलित करता है

उदाहरण

इस उदाहरण में, हम ref से जो मूल्य प्राप्त करेंगे, useImperativeHandle केवल फ़ंक्शन blur जिसे हमने अपने useImperativeHandle में घोषित किया है। इसमें कोई अन्य गुण नहीं होंगे ( मैं इसे प्रदर्शित करने के लिए मान लॉग कर रहा हूं )। फ़ंक्शन स्वयं भी "अनुकूलित" है जो आप सामान्य रूप से अपेक्षा करते हैं उससे अलग व्यवहार करते हैं। यहाँ, यह document.title सेट करता document.title और ब्लर आह्वान होने पर इनपुट को blur है।

const MyInput = React.forwardRef((props, ref) => {
  const [val, setVal] = React.useState('');
  const inputRef = React.useRef();

  React.useImperativeHandle(ref, () => ({
    blur: () => {
      document.title = val;
      inputRef.current.blur();
    }
  }));

  return (
    <input
      ref={inputRef}
      val={val}
      onChange={e => setVal(e.target.value)}
      {...props}
    />
  );
});

const App = () => {
  const ref = React.useRef(null);
  const onBlur = () => {
    console.log(ref.current); // Only contains one property!
    ref.current.blur();
  };

  return <MyInput ref={ref} onBlur={onBlur} />;
};

ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>

useLayoutEffect

हालांकि कुछ हद तक इसी तरह का उपयोग करने के लिए useEffect() , यह इस बात में भिन्न है कि यह प्रतिक्रिया के बाद डोम के अद्यतन के बाद चलेगा। दुर्लभ मामलों में उपयोग किया जाता है जब आपको अपडेट के बाद तत्वों के बीच की दूरी की गणना करने की आवश्यकता होती है या अन्य पोस्ट-अपडेट गणना / दुष्प्रभाव होते हैं।

हस्ताक्षर का उपयोग करने के लिए समान है, लेकिन यह सभी DOM म्यूटेशन के बाद समान रूप से useEffect है। DOM से लेआउट पढ़ने के लिए इसका उपयोग करें और सिंक्रोनस को पुन: रेंडर करें। उपयोग के अंदर निर्धारित useLayoutEffect को ब्राउजर को पेंट करने का मौका मिलने से पहले , तुल्यकालन में फ्लश किया जाएगा।

उदाहरण

मान लीजिए कि आपके पास एक बिलकुल तैनात तत्व है जिसकी ऊँचाई भिन्न हो सकती है और आप इसके नीचे एक और div स्थिति बनाना चाहते हैं। आप माता-पिता की ऊंचाई और शीर्ष गुणों की गणना करने के लिए getBoundingCLientRect() का उपयोग कर सकते हैं और फिर उन्हें केवल बच्चे की शीर्ष संपत्ति पर लागू कर सकते हैं।

यहाँ आप उपयोग करना useLayoutEffect बजाय उपयोग के बजाय प्रयोग करें। नीचे दिए गए उदाहरणों में देखें क्यों:

उपयोग के साथ: ( useEffect व्यवहार पर ध्यान दें)

const Message = ({boxRef, children}) => {
  const msgRef = React.useRef(null);
  React.useEffect(() => {
    const rect = boxRef.current.getBoundingClientRect();
    msgRef.current.style.top = `${rect.height + rect.top}px`;
  }, []);

  return <span ref={msgRef} className="msg">{children}</span>;
};

const App = () => {
  const [show, setShow] = React.useState(false);
  const boxRef = React.useRef(null);

  return (
    <div>
      <div ref={boxRef} className="box" onClick={() => setShow(prev => !prev)}>Click me</div>
      {show && <Message boxRef={boxRef}>Foo bar baz</Message>}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("app"));
.box {
  position: absolute;
  width: 100px;
  height: 100px;
  background: green;
  color: white;
}

.msg {
  position: relative;
  border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>

उपयोग के साथ

const Message = ({boxRef, children}) => {
  const msgRef = React.useRef(null);
  React.useLayoutEffect(() => {
    const rect = boxRef.current.getBoundingClientRect();
    msgRef.current.style.top = `${rect.height + rect.top}px`;
  }, []);

  return <span ref={msgRef} className="msg">{children}</span>;
};

const App = () => {
  const [show, setShow] = React.useState(false);
  const boxRef = React.useRef(null);

  return (
    <div>
      <div ref={boxRef} className="box" onClick={() => setShow(prev => !prev)}>Click me</div>
      {show && <Message boxRef={boxRef}>Foo bar baz</Message>}
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("app"));
.box {
  position: absolute;
  width: 100px;
  height: 100px;
  background: green;
  color: white;
}

.msg {
  position: relative;
  border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>

useDebugValue

कभी-कभी आप कुछ मूल्यों या गुणों को डिबग करना चाहते हैं, लेकिन ऐसा करने के लिए महंगे संचालन की आवश्यकता हो सकती है जो प्रदर्शन को प्रभावित कर सकती है।

useDebugValue केवल तभी कहा जाता है जब रिएक्ट useDebugValue खुले होते हैं और संबंधित हुक का निरीक्षण किया जाता है, जिससे प्रदर्शन पर कोई प्रभाव नहीं पड़ता है।

useDebugValue का उपयोग रिएक्ट DevTools में कस्टम हुक के लिए एक लेबल प्रदर्शित करने के लिए किया जा सकता है।





reactjs