Simple Ways to Listen to Events Across React.js Components

Simple Ways to Listen to Events Across React.js Components
folder-tree Development time-clock

without hooks, flux, thunk, redux and react-redux

There comes a point in your life, when you JUST want to click a button in one component and JUST make something happen in another component of your application

class Emitter extends React.Component {
    _handleButtonClick() {
        console.log('clicked')
    }
    render() {
        return <button onClick={this._handleButtonClick}>
            Click me
        </button>;
    }
}
class Listener extends React.Component {
    state = {
        text: 'Initial text, lol',
    };
    render() {
        return <div>{ this.state.text }</div>;
    }
}
function App() {
    return (
        <div className="App">
            <Emitter />
            <Listener/>
        </div>
    );
}
export default App;

Maybe you don’t have much time and you don’t want to set up redux, with reducers, actions, actionTypes, constants and then connect() and mapStateToProps and mapDispatchToProps. And just maybe you don’t “worry about scalability” (I hate this). Maybe it’s supposed to stay that way: just a button, you click on it, and something happens in another component.

It occurred to me that I don’t know an easy way to do that in React, so I tried to research ones so you don’t have to. Also I’ll list a few difficult but “proper” ways.

Listen to events in another component by passing props

I think this method requires least knowledge of react-specific syntax.

class Emitter extends React.Component {
    render() {
        return <button onClick={this.props._handleButtonClickParent}>
            Click me 
        </button>;
    }
}
class Listener extends React.Component {
   render() {
        return <div>{ this.props.textChanged ? 
                        "You clicked a button" : "Initial text, lol" }</div>;
    }
}
class App extends React.Component  {
    state = {
        textChanged: false,
    };
    _handleButtonClickParent = () => {
        this.setState({textChanged: true})
    };
    render() {
        return <div className="App">
            <Emitter _handleButtonClickParent={this._handleButtonClickParent}/>
            <Listener textChanged={this.state.textChanged}/>
        </div>
    }
}
export default App;

So essentially now all the important things are happening in the parent component and we’re just passing props to children. When you click a button, a _handleButtonClickParent is triggered, it changes state of a parent component and passes a flag textChanged to Listener. Listener can do everything with it, but for now, it just changes the text.

Listen to events in another component using refs

So we’re creating a ref in a parent component from <Listener>component, that way we can call its methods in a parent component. I like this way a bit better since this way you at least can put some meaningful logic in you child component. Except just reacting to flags

import React from 'react';
import './App.css';
class Emitter extends React.Component {
    render() {
        return <button onClick={this.props._handleButtonClickParent}>
            Click me
        </button>;
    }
}
class Listener extends React.Component {
    state = {
        text: "Initial text, lol"
    };
    _handleButtonClicked = () => {
        this.setState({text: "You clicked a button"});
    };
    render() {
        return <div>{ this.state.text }</div>;
    }
}
class App extends React.Component  {
    state = {
        textChanged: false,
    };
    _handleButtonClickParent = () => {
        this.listener._handleButtonClicked();
    };
    render() {
        return <div className="App">
            <Emitter _handleButtonClickParent={this._handleButtonClickParent}/>
            <Listener  ref={ref => { this.listener = ref; }} />
        </div>
    }
}
export default App;

A bit weird way to listen for events: through window

I guess it’s the easiest, but it looks really wrong

import React from 'react';
import './App.css';
class Emitter extends React.Component {
    _handleButtonClick = () => {
        const event = new CustomEvent('button-clicked');
        window.dispatchEvent(event);
    };
    render() {
        return <button onClick={this._handleButtonClick}>
            Click me
        </button>;
    }
}
class Listener extends React.Component {
    state = {
        text: "Initial text, lol"
    };
    componentDidMount() {
        window.addEventListener('button-clicked', () => {
            this.setState({text: "You clicked a button"})
        })
    }
    render() {
        return <div>{ this.state.text }</div>;
    }
}
class App extends React.Component  {
    render() {
        return <div className="App">
            <Emitter/>
            <Listener/>
        </div>
    }
}
export default App;

But it works nonetheless. No props, refs, hooks etc. You just emit event in one component and listen to it in another one. But it looks so “non-react” that you better use it only in projects where you’re the only one developer, or everyone will laugh at you.

Correct but even harder ways:

P.S. How I would listen to events in vue.js

After writing all this it occurs to me that except the wrong way with window, everything else is not so simple. So how would I do it in vue.js?

import Vue from 'vue'
Vue.component('emitter', {template:
      '<button @click="$root.$emit(`button-clicked`)">Click me</button>'
});
Vue.component('listener', {
  template: "<div>{{text}}</div>",
  data: function () { return { 
    text: 'Initial text'
  }},
  mounted() {
    this.$root.$on('button-clicked', () => this.text = 'Button clicked')
  }
});
const App = Vue.component('App', {template:
      "<div id='app'><emitter/><listener/></div>"
});
new Vue({render: h => h(App)}).$mount('#app');

Yeah, it’s that easy.

 

Code is in the repos:

https://github.com/nomadicsoft/example-simple-vue-events-listening

https://github.com/nomadicsoft/example-simple-react-events-listening

 

Latest publications

Extracting Relations to Traits in Laravel Models
Extracting Relations to Traits in Laravel Models

Hey maybe it’s just me, but maybe you also noticed that once the project becomes big, models tend to grow exponentionally. While this is not bad by itself, but up to 80% of the code is Laravel relations which eat up all the screen space and you have to constantly scroll through them to get […]

folder-tree Development
How to Find a Professional on Upwork for Your Application Development
How to Find a Professional on Upwork for Your Application Development

There are a lot of freelancers out there. So if you need to develop an app, or fix something or whatever, you will get dozens of proposals in a matter of hours. But don’t be fooled, it doesn’t mean that you have dozens of viable candidates really. Writing a good job posting is 90% of […]

folder-tree Management
Simple Desktop Application Opening a Website Using Electron-js
Simple Desktop Application Opening a Website Using Electron-js

Fastest way to have a meaningful desktop app which actually does something is to use electron js and just open a website inside a webview: All in all it’s a pretty simple and straightforward task, just a few notes along the way. You can start by cloning https://github.com/electron/electron-quick-start or https://github.com/nomadicsoft/electron-webview-quickstart which is essentially the same […]

folder-tree Development
Remove  dynamic-content-widget elementskit_template and Other Elementskit Content From Google Index
Remove dynamic-content-widget elementskit_template and Other Elementskit Content From Google Index

WordPress is the best engine when it comes to blogs and a lot of other content-heavy applications. Almost all the developers hate it because it’s really hard to understand where a lot of stuff is coming from and how to handle it. This one I admit might be not useful for everyone, but took me […]

folder-tree Development
Ecommerce info block

Hire a eCommerce Web or App Developer

Custom eCommerce development starts with your needs. No matter what size your business is, crafting killer websites or robust applications with Nomadic Soft is a winning strategy. Our development team will always use the latest tech tools to build your business interactive and engaging web interfaces and applications.

Contact us to learn more

Contact Us

By sending this form I confirm that I have read and accept Nomadic soft Privacy Policy
×
Thanks!
Sent!
×
Error!