Events

Sandstone has a convenient way for you to define custom events and event listeners for your components via two simple decorator functions.

Dispatching events

To define an event, create a method on your component that returns your event payload and decorate it with Event like so:

import { WebComponent, Event } from 'sandstone';

class ThemeSelectButton extends WebComponent {
    @Event('THEME_CHANGED')
    changeTheme() {
        // ...Optionally do stuff
        return this.state.theme;
    }

    render() {
        return <button class="theme-btn" onClick={this.changeTheme}>Like</button>
    }
}

Event decorator has an optional second argument for custom senderName. By default it's set to component name. If you don't want to use a decorator, you can also dispatch events using this.trigger

import { WebComponent } from 'sandstone';

class ThemeSelectButton extends WebComponent {
    changeTheme = () => {
        // ...Optionally do stuff
        this.trigger('THEME_CHANGE', this.state.theme); 
    }

    render() {
        return <button class="theme-btn" onClick={this.changeTheme}>Like</button>
    }
}

this.trigger has an optional third argument for custom sender name.

Listening to events

Every component has a .on method for subscribing to events. To listen to an event, you can do the following:

import { WebComponent } from 'sandstone';

class ThemedElement extends WebComponent {
    componentDidMount() {
        this.on('THEME_CHANGED', this.handleEvent); // Handlers are autobound
    }


    handleEvent(payload) {
        this.setState({
            selectedTheme: payload
        });
    }

    render() {
        return <div class={this.state.selectedTheme}>...</div>
    }
}

Unwrapping promises

When dispatching events, you can pass a promise as event payload. Sandstone will wait for the promise to resolve and dispatch the event with the result of that promise as a payload. This works with both @Event decorator and this.trigger. I.e:

import { WebComponent } from 'sandstone';
import axios from 'axios';

class MyElement extends WebComponent {
    componentDidMount() {
        this.on('GET_DATA', this.handleEvent);
    }

    handleData = ({ data }) => {
        this.setState({ data });
    }

    getData = () => {
        this.trigger(axios.get('/api/user/profile'));
    }

    render() {
        return (
            <div>
                 <button onClick={this.getData}>Get Data</button>
            </div>
        )
    }
}

Next: Shadow DOM →

results matching ""

    No results matching ""