58

I'm new to react world and I have line like this:

<Button onClick={() => console.log("hello")}>Button</Button>

and on click you will get hello printed on the console. Now change the line to:

<Button onClick={() => <NewComponent />}>Button</Button>

now on click on the button, I expect the NewComponent to be rendered. But it doesn't.

I'm not sure, why that is the case. Note that I have the above code in the render method.

6
  • 2
    That's just not how it works. Where would you expect the component to render? Commented Nov 21, 2015 at 5:47
  • 2
    But where? Above the button? Below the button? Inside the button? Inside the onClick attribute? Somewhere else? Currently your click handler is something like function() { React.createElement(...); }. It doesn't do anything with the element that was created. Commented Nov 21, 2015 at 5:49
  • @FelixKling: Oh now it make sense, so we need to do something like React.render and give the area in which need to be renderd Commented Nov 21, 2015 at 5:50
  • Right. But your component should probably just have state and render the component next to the button after the button was clicked. Commented Nov 21, 2015 at 5:51
  • 1
    @FelixKling: Thanks now it make sense, you can provide the answer I can accept. Commented Nov 21, 2015 at 5:52

5 Answers 5

98

You probably want to have a stateful component that shows the other component next to the button after it was clicked. All you need to do is track whether the button was clicked:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      showComponent: false,
    };
    this._onButtonClick = this._onButtonClick.bind(this);
  }

  _onButtonClick() {
    this.setState({
      showComponent: true,
    });
  }

  render() {
    return (
      <div>
        <Button onClick={this._onButtonClick}>Button</Button>
        {this.state.showComponent ?
           <NewComponent /> :
           null
        }
      </div>
    );
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Hi.what if i want to load only NewComponent on the same page overwriting all the other components without using react router?
@MustafaMuawia: No.
For some reason, it shows me this error: TypeError: Cannot read property 'onButtonClick' of undefined
@AbhirajshriWinsome: You are likely accessing this.onButtonClick in a function who's this value does not point to the component instance.
10

Here's a CodePen to show it in action.

HTML

<div id="root">loading...</div>

JSX

class NewComponent extends React.Component {
  render() {
    return (
      <div {...this.props}>
        new component
      </div>
    );
  }  
}

class Button extends React.Component {
  render() {
    return (
      <button {...this.props}>
        click
      </button>
    );
  }  
}

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      clicked: false
    };

    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState({
      clicked: true
    });
  }

  render() {
    return (
      <div>
        <Button onClick={this.handleClick} />
        {this.state.clicked ? <NewComponent /> : null}
      </div>
    );
  }
};

React.render(
  <App />,
  document.getElementById("root")
);

1 Comment

A pen never helped so much. I'm starting to get the conditional rendering issue about React :) thanks!
6

Use instead: {this.state.clicked && <NewComponent />}

Comments

2

you can use withRouter() of react-router-dom. When we use <Route path='/path' component={newComponent} /> react-router-dom passes three props "history,location and match" , you can use push() function of history props in your onClick just by passing your whole component in withRouter() as:

JSX

import { withRouter } from 'react-router-dom' ;
import Button from 'buttonFolder/button.component';
const yourComponent = ({history}) => {

return (
       <Button onClick{() => history.push.('/path')}> New componentPage </Button>
)};

export default withRouter(yourComponent);

Comments

0

You need to set state to track visibility of the component. Default it to false, and onclick set state to true. In your render do something like {this.state.visible ? : null}

Comments

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.