2

I'm new to React (also fairly new to Javascript in general) and trying to wrap my head around what can be done with setState to re-render React elements on the page.

Is there a way to use setState in one component to change the state of a completely different element (i.e. components that maybe only share the DOM root node)? I've tried to implement this but am getting the error "myElementOne.setState is not a function".

Is there a another way I should be approaching this?

var App = React.createClass({
    render() {
        return (
            <div>
                <ElementOne id="abc12345"/>
                <ElementTwo/>
            </div>
        );
    }
});

var ElementOne = React.createClass({
    getInitialState() {
        return ({isShowing: true});
    },

    render() {
        if (this.state.isShowing) {
            return (
                <div id="abc12345">
                    <h1>Hello World!</h1>
                </div>
            );
        } else {
            return <div/>;
        }
    }
});

var ElementTwo = React.createClass({
    render() {
        return <a href="#" onClick={this.toggle.bind(null,this)}>Click here to Show/Hide!</a>;
    },

    toggle() {
        var myElementOne = document.getElementById("abc12345");
        myElementOne.setState({isShowing: false});
    }
});

ReactDOM.render(<App/>,document.getElementById('content'));

1 Answer 1

1

You can achieve this in the following way: http://codepen.io/PiotrBerebecki/pen/YGEmBE

The idea is to:

  1. Maintain state in your parent component (App)
  2. Pass this state to ElementOne
  3. Pass ability to modify the state by a callback function passed to ElementTwo

Full code:

var App = React.createClass({
    getInitialState() {
      return ({
        isShowingInParent: true
      });
    },

    toggleInParent() {
      this.setState({
        isShowingInParent: !this.state.isShowingInParent
      });
    },

    render() {
        return (
            <div>
                <ElementOne id="abc12345" isShowing={this.state.isShowingInParent}/>
                <ElementTwo toggle={this.toggleInParent}/>
            </div>
        );
    }
});

var ElementOne = React.createClass({
    render() {
        if (this.props.isShowing) {
            return (
                <div id="abc12345">
                    <h1>Hello World!</h1>
                </div>
            );
        } else {
            return <div/>;
        }
    }
});

var ElementTwo = React.createClass({
    render() {
        return <a href="#" onClick={this.props.toggle.bind(this)}>Click here to Show/Hide!</a>;
    }
});

ReactDOM.render(<App/>,document.getElementById('content'));
Sign up to request clarification or add additional context in comments.

3 Comments

I've just updated my code and added additional explanation. Does it solve your problem?
partially yes, thank you :) but I'm still keen to understand whether or not there is a way to invoke another React element's setState without having to pass information via a parent node. Do you know whether or not this can be done? Or does a parent node always need to be used?
Sorry, I've missed your question. Without involving any third party libraries, you can pass information to grandchildren in pure React. This can be done using the context feature. Here you can find a nice summary of communication in react: andrewhfarmer.com/component-communication, facebook.github.io/react/docs/context.html, here are the React docs about context

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.