简体   繁体   中英

How do i pass data up from a child web component to it's direct parent element

I need to basically pass a value down to my web component, I will then do some random thing to it, now I want to pass that new value back up to my React Comnponent. How do I do that?

function MyReactcomp() {
   const [state, setState] = useState("Justin is cool");
   return (
        <div className="Wrapper">
           <customweb-component state={state} />
        </div>
    );
}

Now inside the customweb-component, I will change state to "No your not!!". How can I pass this value back up from my web component to my Rea t Copmponent? I know I can pass a function down because you can only pass strings down

Instead of querying for DOM, you should use React's Ref as shown below:

function MyReactcomp() {
  const [state, setState] = useState("Justin is cool");

  // Hold the web component reference here
  const myWebComp = useRef();

  useEffect(() => {
    myWebComp.current?.addEventListener('tab-select', (event) => {
      setState(Object.keys(adminTabs[event.detail.tabIndex]));
    });
  }, []);

  return (
    <div className="Wrapper">
      <customweb-component ref={myWebComp} state={state} />
    </div>
  );
}

And, you if you need to observe for changes in your referenced element, then you can use plain useState to hold reference to the element:

function MyReactcomp() {
  const [state, setState] = useState("Justin is cool");

  // Hold the web component reference here
  const [webComp, setWebComp] = useState(null);

  useEffect(() => {
    webComp?.addEventListener('tab-select', (event) => {
      setState(Object.keys(adminTabs[event.detail.tabIndex]));
    });
  }, [webComp]);

  return (
    <div className="Wrapper">
      <customweb-component ref={setWebComp} state={state} />
    </div>
  );
}

If you find doing this too many times, you can abstract this behavior into custom hooks. For example:

function useWebCompProp(ref, initialValue) {
  const [state, setState] = useState(initialValue);

  useEffect(() => {
    ref.current?.addEventListener('onState', (event) => {
      // Update the state here
      setState(event.detail);
    });
  }, []);

  const setter = (newState) => {
    setState(newState);
    ref.current?.state = newState;
  };

  return [state, setter];
}


function useWebCompEvent(eventName, callback) {

  // Hold the web component reference here
  const myWebComp = useRef();

  useEffect(() => {
    myWebComp.current?.addEventListener(eventName, callback);
  }, []);

  return myWebComp;
}


function MyReactcomp() {

  const myWebComp = useWebCompEvent(eventName, (event) => {
    setState(Object.keys(adminTabs[event.detail.tabIndex]));
  });

  const [state, setState] = useWebCompProp(myWebComp, "Justin is cool");

  return (
    <div className="Wrapper">
      <customweb-component ref={myWebComp} />
    </div>
  );
}

In react, the transfer of data is 1-way only, ie, from Parent-to-Child However, if you need to have a handler in the parent element for some data change in the child element, you can use Lifting Up State This could help achieving what you need.

If not, please provide more details about the actual case scenario

I figured out that you need to attach a custom event handler to an element in your Lit-html template. You can then use getElementById or something to that effect and listen for the event in the parent component.

This is a combination of my answer and Harshal Patil's he took into account that using Reacts built-in features for manipulating the DOM is preferable to manipulating it directly.

import React, { useEffect, useRef } from 'react';

function MyReactcomp() {
   const [state, setState] = useState("Justin is cool");
   const webCompRef = useRef();
   useEffect(() => {
       webCompRef.addEventListener('tab-select', (event) => {
           setState("No he is not!!")
       })    

   }, []}
    return (
         <div className="Wrapper">
              <customweb-component ref={webCompRef} state={state} />
         </div>
     );
}

This pattern will allow you to pass your data down through the web components attributes. You can then listen for your native or custom events. This is cool because now components can cross frameworks and libraries, if one team is using React and the other is using Angular they can share components and keep there UI in sync.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM