31

In Vue.js we can emit custom events along with a parameter like

this.$emit('bark', 3);

and then we can listen to this event on the parent component like

<parent-component @bark=handleBark />

handleBark (howManyTimes) {
    console.log(howManyTimes);
    // logs 3
}

How can we do that in React?

Pooria Han
  • 597
  • 1
  • 4
  • 19
  • https://stackoverflow.com/questions/21951734/react-js-custom-events-for-communicating-with-parent-nodes does this answer your question? – illiteratewriter Nov 17 '20 at 13:36
  • @illiteratewriter Actually no :) I need an example of how it should be done in React or "React way". From what I understood Event bubbling doesn't exist in React, then how should we write this simple `bark` example in React? – Pooria Han Nov 17 '20 at 13:56
  • So assume you have a parent and child component. In you child component you are doing some action and you need to pass that event or some custom value to the parent component you can use a callback function, is that what you are looking, If yes, i can add a sample snippet code. Let me know – Learner Nov 17 '20 at 13:58
  • @DILEEPTHOMAS Yes. exactly :) – Pooria Han Nov 17 '20 at 14:05
  • Sure will add the code snippet for the same. – Learner Nov 17 '20 at 14:12
  • Added @PooriaHan let me know if it helped you. – Learner Nov 17 '20 at 14:45

3 Answers3

21

As @usafder, mentioned the way. I am just adding the basic callback function for an input field. So on the console you can see the current value.

Basically callback function is the way to get the data from the Child component.

Parent.js

import React from "react";
import Child from "./Child";

export default function App() {
  const parentHandleChange = (e) => {
    console.log(e.target.value);
  };

  return (
    <div>
      <Child handleChange={parentHandleChange} />
    </div>
  );
}

Child.js

import React from "react";

const Child = (props) => {
  return <input onChange={props.handleChange} />;
};

export default Child;

Working codesandbox

Addition to it if you need return a custom value use like this

<Child onHandleChange={() => parentHandleChange(10)}

Because in this it won't call every-time if you want pass a value.

Learner
  • 8,379
  • 7
  • 44
  • 82
  • How would you pass this to a component stored in a variable? :) I don't seem to understand HOCs and how to pass that data through a HOC. – ii iml0sto1 Oct 31 '22 at 13:53
14

You just simply pass down the custom event handler as props.

For example if you have Parent and Child functional components. You can then define the custom event handler in the Parent component like:

function Parent(props) {
  const handleBark = (howManyTimes) => {
    console.log(howManyTimes);
  };
  
  // note below I am sending the handleBark method to Child as props
  return (<Child bark={handleBark} />);
}

and then inside the Child component you can simply call it as:

props.bark(10);
usafder
  • 791
  • 5
  • 17
6

You can also use this library, Evento, that I created to replicate Svelte's createEventDispatcher() and Vue's $emit.

You have to create the event emitter (named by convention evento) using the hook, and use the dispatcher as you would do with $emit by passing the name of the event and the payload :

const Dog = (props) => {
  const evento = useCreateEvento(props)
 
  return <button onCLick={() => evento('bark', 3)}>wof</button>
}

The parent Component will be able to listen to the Event as it would listen to a React Event: by using on + the capitalized name of the Component Event. The data will be stored in event.detail.

<Dog onBark={e => console.log(`barked ${e.detail} times`)} /> 
/* will log 'barked 3 times'*/
Aÿlo
  • 271
  • 3
  • 7