簡體   English   中英

React.js,為什么我的類組件不重新渲染元素,但是功能組件可以工作?

[英]React.js, why my class component doesn't rerender the element, but functional component can work?

我是react.js的新手,只需按照教程進行即可。 這是我的代碼。 最初,我嘗試使用Component'Greeting'類讓它在單擊按鈕后顯示不同的單詞,但我不知道出了什么問題,它沒有重新呈現該元素,並且僅使用Greeting的construtor()方法打電話一次。 注釋掉的代碼功能組件“問候”效果很好。 不知道有什么區別:(

class GreetingGuest extends React.Component {
    render() {
        return (
            <h3>hello Guest, Click login button !!! </h3>
        );
    }
}

class GreetingUser extends React.Component {
    render() {
        return (
            <h3>You have logged in, welcome !!!</h3>
        );
    }
}

class Greeting extends React.Component {
  constructor(props) {
      super(props);   
      console.log('Greeting.state.is_logon = ', props.is_logon);
      this.state = {is_logon: props.is_logon};
  }

  render() {
      let welcome_msg = null;
      if (this.state.is_logon) {
          welcome_msg = <GreetingUser />;                 
      }else {
          welcome_msg = <GreetingGuest />;    
      }
      return welcome_msg; 
  }
}

//function Greeting(props) {
//    const is_logon = props.is_logon;
//    if (is_logon) {
//        return <GreetingUser />;
//    }
//    return <GreetingGuest />;
//}

class LoginComponent extends React.Component {
    constructor(props) {        
        super(props);           
        this.state = {is_logon: false};
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState(prevState => ({
            is_logon: !prevState.is_logon
        }));
    }

    render() {
        let button = null;
        let greeting = null;

        if (this.state.is_logon) {
            button = (
                <button onClick={this.handleClick}>Logout</button>
            );

            greeting = <Greeting is_logon={this.state.is_logon} />
        }else {
            button = (
                <button onClick={this.handleClick}>Login</button>
            );
            greeting = <Greeting is_logon={this.state.is_logon} />
        }
        return (
            <div>
                {greeting}
                {button}
            </div>
        );
    }
}

ReactDOM.render(
    <LoginComponent />,
    document.getElementById('Login')
)

HTML:

<html>
<body>
     <div id="Login"></div>
</body>
<html>

類組件不重新呈現的原因是因為您已從構造函數中存儲了logged_in道具的狀態,並且構造函數僅被調用一次。 而且狀態只能在組件內部進行修改。

要解決此問題,您有2個選項;

使用componentWillReceiveProps ,並使用新的logged_in道具更新本地狀態。

componentWillReceiveProps(nextProps) {
  if (nextProps.logged_in !== this.state.logged_in) {
    this.setState({ logged_in: nextProps.logged_in });
  }
}

要么; 不要使用狀態,而是直接使用道具。

  render() {
      let welcome_msg = null;
      if (this.props.is_logon) {
          welcome_msg = <GreetingUser />;                 
      }else {
          welcome_msg = <GreetingGuest />;    
      }
      return welcome_msg; 
  }

我認為您應該使用后者,因為父組件已經維護了狀態。

老實說,我以前發布的答案是錯誤的。 這是因為您發布問題的方式是,添加基於功能的組件后一切正常。 然后,我使用您的代碼創建了一個項目,並找出了代碼中的幾個問題。

首先,您在此處在redux之外本地維護狀態。 您正在將登錄狀態從父LoginComponent到名為Greeting的子組件,如下所示。

greeting = <Greeting is_logon={this.state.is_logon} />

這被作為道具的子組件被傳遞Greeting在這種情況下。 請記住,React使用一種數據流方式

現在,您可以從該子組件中使用this.props訪問數據,如下所示。 您無需在那里維護任何本地狀態。 在“ Greeting組件中進行以下更改。

  constructor(props) {
      super(props);
  }

然后確保您從this.props中訪問值,而不是像這樣的任何本地狀態對象。

 render() {
      let welcome_msg = null;
      if (this.props.is_logon) {
          welcome_msg = <GreetingUser />;
      }else {
          welcome_msg = <GreetingGuest />;
      }
      return welcome_msg;
  }
}

這解決了問題。 編碼愉快!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM