简体   繁体   English

单击按钮后组件不呈现

[英]Component does not render on button click

I've got two components: button and progress bar. 我有两个组件:按钮和进度栏。 I would like to render the progress bar instead of the button once the button is clicked. 单击按钮后,我想呈现进度条而不是按钮。 Click is handled correctly, when I place the alert before the return it is displayed. 当我在返回之前显示警报时,单击被正确处理。 Progress bar itself is rendered correctly as well. 进度栏本身也正确呈现。 So it's only a problem with rendering it on button click. 因此,在单击按钮时呈现它只是一个问题。 I am very new to React and I cannot see why my code doesn't work. 我对React很陌生,我看不出为什么我的代码无法正常工作。 Could you help me to understand the problem? 你能帮我理解这个问题吗?

class ProgressButton extends React.Component {

  constructor () {
    super()
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick () {
    return (
      <Bar />
    )
  }

  render () {
    return (
      <Button onClick={this.handleClick}>
        Click!
      </Button>
    );
  }

}

class Bar extends React.Component {

  render () {
    return (
      <ProgressBar>
        Here the progress will be shown.
      </ProgressBar>
    );
  }
}

React will only render what's in the render functions, the fact that some random function happen to return a component has no impact as long as that component isn't a part of some component's render function. React只会渲染render函数中的内容,只要某个随机函数碰巧返回了一个组件,只要该组件不是某个组件的render函数的一部分,就不会产生任何影响。

You could solve this instead by having some state that determines if the Bar should render or not, and toggling that with the click. 您可以通过具有某种状态来确定是否应渲染Bar并通过单击切换该状态来解决此问题。

Something along 沿途

class ProgressButton extends React.Component {

  constructor () {
    super()
    this.handleClick = this.handleClick.bind(this);
    this.state = {loading: false}; {/* state we use whether to show bar or not */}
  }

  handleClick () {
    this.setState({loading: true}); {/* when button click we remember it */}
  }

  render () {
    if (this.state.loading) {
       return (
         <Bar /> {/* <-- here we have it inside the render function! */}
       );
    } else {
        return (
          <Button onClick={this.handleClick}>
            Click!
          </Button>
        );
     }
  }

}

Returning a JSX from a function would not magically render it! 从函数返回JSX不会神奇地渲染它! You need to somehow put that JSX somewhere in the render function. 您需要以某种方式将JSX放在render函数中。

Here is one way to do so: 这是一种方法:

class ProgressButton extends React.Component {
  constructor() {
    super();
    this.state = {
      showBar: false,
    };
    this.handleClick = this.handleClick.bind(this);
  }

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

  render() {
    if (this.state.showBar) {
      return <Bar />;
    }
    return <Button onClick={this.handleClick}>Click!</Button>;
  }
}

You cannot update a view like this and it is against the rules. 您不能像这样更新视图,这违反了规则。 (As I am also a new ReactJS developer I have ongoing experience.) (因为我也是ReactJS的新开发者,所以我有持续的经验。)

  1. Use a conditional render. 使用条件渲染。 For example https://reactjs.org/docs/conditional-rendering.html 例如https://reactjs.org/docs/conditional-rendering.html

  2. Use a modal with the progress bar and display it on the button click action. 在进度条上使用模式,并在按钮单击操作上显示它。

You cannot return components from normal functions,you can do the following way to render the progressbar 您无法从正常函数返回组件,可以通过以下方式呈现进度条

class ProgressButton extends React.Component {

  constructor () {
    super()
    this.handleClick = this.handleClick.bind(this);
    this.state = {openBar:false}
  }

  handleClick () {
   this.setState({openBar:true})
  }

  render () {
    return (
      <div>
      <Button onClick={this.handleClick}>
        Click!
      </Button>
       {this.state.openBar &&<Bar/>}
      </div>
    );
  }

}

class Bar extends React.Component {

  render () {
    return (
      <ProgressBar>
        Here the progress will be shown.
      </ProgressBar>
    );
  }
}

That just won't work. 那只是行不通的。 You could try something like this 你可以尝试这样的事情

class ProgressButton extends React.Component {

  constructor () {
    super()
    this.state = {
        showBar : false;
    }
  }

  handleClick = () => {
    this.setState({showBar: true});
  }

  render () {
    var { showBar } = this.state;
    return (
      <React.Fragment>
          <Button onClick={this.handleClick}>
            Click!
          </Button>
          {showBar && <Bar/>}
      </React.Fragment>
    );
  }

}

class Bar extends React.Component {

  render () {
    return (
      <ProgressBar>
        Here the progress will be shown.
      </ProgressBar>
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM