我如何将数据从子 Web 组件向上传递到它的直接父元素

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

我基本上需要将一个值向下传递到我的 Web 组件,然后我会对它做一些随机的事情,现在我想将该新值传递回我的 React Comnponent。我该怎么做?

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

现在在 customweb-component 中,我将状态更改为“No your not!!”。我怎样才能将这个值从我的网络组件传回给 我的 Rea t 组件?我知道我可以向下传递一个函数,因为你只能向下传递字符串

在 React 中,数据传输仅为单向传输,即来自 Parent-to-Child 但是,如果您需要在父元素中为子元素中的某些数据更改提供处理程序,则可以使用 Lifting Up State 这可能有助于实现您的需求。

如果不是,请提供有关实际案例场景的更多详细信息

我发现您需要将自定义事件处理程序附加到 Lit-html 模板中的元素。然后您可以使用 getElementById 或类似的东西来监听父组件中的事件。

这是我的回答和 Harshal Patil 的结合,他考虑到使用 Reacts built-in 特性来操纵 DOM 比直接操纵它更可取。

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>
     );
}

此模式将允许您通过 Web 组件属性向下传递数据。然后您可以侦听您的本机或自定义事件。这很酷,因为现在组件可以跨框架和库,如果一个团队使用 React 而另一个团队使用 Angular,他们可以共享组件并保持 UI 同步。

而不是查询 DOM,您应该使用 React 的 Ref,如下所示:

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>
  );
}

并且,如果您需要 观察 以查看引用元素的变化,那么您可以使用纯 useState 来保存对元素的引用:

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>
  );
}

如果您发现这样做的次数过多,可以将此行为抽象为自定义挂钩。例如:

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>
  );
}