0

I have a quite complex React16/Redux single page application.

I am trying to find a way to trigger a CSS animation on a component or DOM element (let's call it Foo component), when a user pushes a button (let's call it Bar component) which stands 'far away' from this component/DOM element.

I would like to avoid to pass through a list of callbacks, or through Redux, with a kind of observer pattern, so that I can do something like:

class Bar extends React.Component {
    ...
    onButtonClick() {
        allFooComponentsOnThePageShouldBlinkFor1Second();
    }
}

Is there a simple way to do so?

matt
  • 1,046
  • 1
  • 13
  • 26

1 Answers1

0

So, your best bet is probably to use Redux, or a similar state management system. That said, you can do this by using a wrapper component's local state as seen in this question. I don't think this will be faster or easier in the long run than using Redux, but here we go:

Your component Wrapper will have some local state which keeps track of whether Bar should be flashing and has a function that changes that state which is passed to Foo. You need to be careful to make sure that the this in the click handler always points to Wrapper. I've done it here with an arrow function. If you would rather use .bind, then you can make that change in your implementation.

class Wrapper extends React.Component {
    // accessible through `this.state`
    state = { fooShouldBlink: false };

    handleClick = () => {
        // arrow function preserves `this` as `Wrapper`
        this.setState({ fooShouldBlink: true }, () => {
            // Resets state after 1 second so that this can be done more than once. 
            // If that's not needed, you can take this out
            setTimeout(() => this.setState({ fooShouldBlink: false }), 1000);
        });
    }

    render () {
        return (
            <div>
                <Bar clickHandler={this.handleClick}/>
                <Foo blinkState={this.state.fooShouldBlink} />
                <Foo blinkState={this.state.fooShouldBlink} />
                <Foo blinkState={this.state.fooShouldBlink} />
            </div>
        );
    }
}

ldtcoop
  • 680
  • 4
  • 14