簡體   English   中英

ReactDOM.render 不會在道具更改時更新組件

[英]ReactDOM.render doesn't update component on props change

我創建了一個非常小的應用程序來演示我的查詢。

下面顯示的代碼具有使用 ReactDOM.render 將組件動態添加到 DOM 的功能,並且該組件帶有一個名為 title 的道具,但是當我更新父組件的標題(狀態)時,DynamicComponent 不會更新。

import React from 'react';
import ReactDOM from 'react-dom';

const DynamicComponent = (props) => {
    return (
        <div style={{ 'border': '2px dotted green' }} >Dynamic Component : {props.title}</div>
    )
}

class App extends React.Component {
    state = {
        title: 'Iam Title'
    }

    addBlock = () => {
        return ReactDOM.render(<DynamicComponent title={this.state.title} />, document.getElementById('dynamiccomponents'))
    }

    render() {
        return (
            <div>
                <div>Value in state: <b>{this.state.title}</b></div>
                <p><b>&lt;DynamicComponent /&gt;</b> Added Initially</p>
                <DynamicComponent title={this.state.title} />
                <br />
                <p><b>&lt;DynamicComponent /&gt;</b> Added By ReactDOM.render will be shown below: </p>
                <div id="dynamiccomponents"></div>



                <button onClick={this.addBlock} >Click to Dynamic Component</button>
                <button onClick={() => this.setState({ title: `Update Title` })} >Update Title</button>
            </div>
        )
    }
}

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

第一個按鈕用於添加 DynamicComponent,按預期工作正常。 第二個按鈕用於更新狀態中的標題,現在標題已更改但 DynamicComponent 仍未更新。

我錯過了什么,我該如何解決這個問題,任何幫助將不勝感激

謝謝

您可以在狀態更改后使用 LifeCycle 方法componentDidUpdate()重新渲染組件

    import React from "react";
import ReactDOM from "react-dom";

const DynamicComponent = props => {
  return (
    <div style={{ border: "2px dotted green" }}>
      Dynamic Component : {props.title}
    </div>
  );
};

class App extends React.Component {
  state = {
    title: "Iam Title"
  };

  addBlock = () => {
    return ReactDOM.render(
      <DynamicComponent title={this.state.title} />,
      document.getElementById("dynamiccomponents")
    );
  };
  componentDidUpdate() {
    return ReactDOM.render(
      <DynamicComponent title={this.state.title} />,
      document.getElementById("dynamiccomponents")
    );
  }

  render() {
    return (
      <div>
        <div>
          Value in state: <b>{this.state.title}</b>
        </div>
        <p>
          <b>&lt;DynamicComponent /&gt;</b> Added Initially
        </p>
        <DynamicComponent title={this.state.title} />
        <br />
        <p>
          <b>&lt;DynamicComponent /&gt;</b> Added By ReactDOM.render will be
          shown below:{" "}
        </p>
        <div id='dynamiccomponents'></div>

        <button onClick={this.addBlock}>Click to Dynamic Component</button>
        <button onClick={() => this.setState({ title: `Update Title` })}>
          Update Title
        </button>
      </div>
    );
  }
}

export default App;

這是因為當您調用addBlock ,您只將<DynamicComponent title={this.state.title} />渲染到<div id="dynamiccomopnents"></div>

當您通過單擊按鈕更新title狀態時,它會重新運行您的應用程序的render函數,但this.addBlock不會在您的render函數中再次運行,因此您的標題不會更新。 您可以通過再次單擊調用this.addBlock的按鈕來驗證這一點。 它將使用更新的標題再次渲染您的組件。

我建議你引入一些狀態來有條件地渲染你的組件,而不是使用ReactDOM.render 這樣,每次運行render方法時都會重新渲染組件。 下面是一個例子:

import React from 'react';
import ReactDOM from 'react-dom';

const DynamicComponent = (props) => {
  return (
    <div style={{ 'border': '2px dotted green' }} >Dynamic Component : {props.title}</div>
  )
}

class App extends React.Component {
  state = {
    title: 'Iam Title',
    showBlock: false,
  }

  addBlock = () => {
    // this method now sets `this.state.showBlock` to true
    this.setState({ showBlock: true });
  }

  renderBlock = () => {
    // return any component you want here, you can introduce some conditional
    // logic or even return nested elements, for example:
    return (
      <div>
        <p>Dynamic Component!</p>
        <DynamicComponent title={this.state.title} />
      </div>
    );
  }

  render() {
    return (
      <div>
        <div>Value in state: <b>{this.state.title}</b></div>
        <p><b>&lt;DynamicComponent /&gt;</b> Added Initially</p>
        <DynamicComponent title={this.state.title} />
        <br />
        <p><b>&lt;DynamicComponent /&gt;</b> Added By ReactDOM.render will be shown below: </p>

        {/* This will run `this.renderBlock` only if `this.state.showBlock` is true */}
        {this.state.showBlock && this.renderBlock()}



        <button onClick={this.addBlock} >Click to Dynamic Component</button>
        <button onClick={() => this.setState({ title: `Update Title` })} >Update Title</button>
      </div>
    )
  }
}

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

ReactDOM.render只渲染元素一次。 它創建了一個不同的樹,它沒有連接到你的第一棵樹。 也就是說,React 不會跟蹤您可能曾經調用過的所有ReactDOM.render ,並且不會使用用於創建它們的數據更新它們

如果您需要在 App 組件之外的 DOM 樹中的某處渲染元素,但您希望它與您的 App 組件連接(以便它對狀態更改做出反應),請使用ReactDOM.createPortal

暫無
暫無

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

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