skip to Main Content

Is it possible to pass data up several levels of child -> parent and do something with that data at each stage without creating new functions at each level? For example, if I have three levels of component:

PARENT

function Parent() {
    const parentFunction = (str) => {
            console.log('Output processed by parent', str)
    };
    return (
        <div>
            <Child onClick={parentFunction} />
        </div>
    );
}

CHILD

function Child({passedFunc}) {

    // DO SOMETHING HERE WITH THE RESULT OF ONCLICK BEFORE PASSINT IT UP
    // TO PARENT

    return (
        <div>
            <GrandChild onClick={passedFunc} label="first" />
            <GrandChild onClick={passedFunc} label="second" />
        </div>
    );
}

GRANDCHILD

function GrandChild({passedFunc, label}) {

    const handle_click = () => {
        passedFunk(label + 'something');
    }

    return (
        <div onClick={handle_click}>{label}</div>

    );
}

When the grandchild is clicked a string is passed up two levels to parent where it is printed to console. But I also want to be able to do something with that data at the first child level before it is passed up and still printed.

2

Answers


  1. Yes you can do something like this

    function Child({ onClick }) {
      const [saved, setSaved] = useState(null);
      const handleGrandchildClick = async (grandchildParam) => {
        await sendToSomeServer(grandchildParam);
      };
    
      useEffect(() => {
        if (saved) {
          // do something with saved
          console.log("Saved:", saved);
        }
      }, [saved]);
    
      return (
        <div>
          <GrandChild
            onClick={async (grandchildParam) => {
              // set state to trigger using useEffect
              setSaved(grandchildParam);
    
              // do something right in this callback function
              await handleGrandchildClick(grandchildParam);
    
              onClick(grandchildParam);
            }}
            label="first"
          />
          <GrandChild onClick={onClick} label="second" />
        </div>
      );
    }
    

    Not sure if this is what you want, but in general you can intercept value of the callback at any layer. But when it becomes too deep, there are several ways to handle it and one of the is to use context (docs).

    Login or Signup to reply.
  2. const Parent = () => {
      const handleParent = (num) => {
        console.log(num); // 101
      };
      return (
        <div>
          Parent
          <Child onClickParent={handleParent} />
        </div>
      );
    };
    
    const Child = ({ onClickParent }) => {
      const handleChild = (num) => {
        onClickParent(num + 100);
      };
      return (
        <div>
          Child
          <GrandChild onClickChild={handleChild} />
        </div>
      );
    };
    
    const GrandChild = ({ onClickChild }) => {
      const handle_click = () => {
        onClickChild(1);
      };
      return (
        <div>
          GrandChild
          <button onClick={handle_click}>button</button>
        </div>
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search