簡體   English   中英

在React中渲染動態子組件

[英]Rendering a dynamic child component in React

我有一個菜單組件,應該在另一個容器組件中動態加載元素。 但是,子元素永遠不會渲染。

App.js

import React, { Component } from 'react';
import './App.css';
import Menu from './components/navigation/Menu';
import Header from './components/navigation/Header';
import Container from './components/navigation/Container';

class App extends Component {
 render() {
    return (
      <div className="App" >
        <Header />
        <Menu OnMenuChange={(appName) => { this.setState({ currentApp: appName }) }} />
        <Container App={this.state.currentApp}/>
      </div>
    );
  }
}


export default App;

Container.js

import React from 'react';
import './container.css';
import { MyApp } from '../../apps';

class Container extends React.Component {

    render() {
        return (
            <div className="container">
                { this.props.App ? <this.props.App /> : null }
            </div>
        );
    }
}

export default Container;

當用戶單擊菜單選項時,它將在app.js級別觸發OnMenuChange,這將更新Container組件。 然后將“ MyApp”元素放入容器div中。

但是,從未在MyApp組件中調用構造函數和render方法。

更新我將菜單項列表移至App.js文件:

let navGroups = [
  {
    links: [
      {
        key: "myApp",
        name: "My App",
        type: MyApp,
      }
    ]
  }
];

然后將該列表傳遞到菜單中,該菜單現在傳遞回“類型”而不是名稱。 由於名稱現在可以在其中包含空格,因此效果更好。

我認為問題可能出在第一次渲染發生時未定義您的state對象,然后阻止對其進行任何形式的更新。 我可能只是將其設置為空對象以對其進行初始化。

class MyComponent extends Component {
  state = {
    App: null
  }
}

示例: https //jsfiddle.net/614ykpgg/9/

讓我們考慮一下這部分JSX轉換為:

<this.props.App />

React.createElement(this.props.App, null)

...現在查看React.createElement功能。 文檔

createElement()

 React.createElement( type, [props], [...children] ) 

創建並返回給定類型的新React元素。 type參數可以是標簽名稱字符串(例如'div''span' ),也可以是React組件類型(類或函數)。

從外觀this.props.App ,您代碼中的this.props.App是一個字符串。 無論該字符串是'div'還是'MyFancyApp' ,React都假定它是HTML標記的名稱(因為它還能做其他事情嗎?)。

如果您想讓React將this.props.App視為組件,則this.props.App的值必須是實際的組件類或函數-而不是帶有組件名稱的字符串。 您可以更改Menu組件以將組件而不是字符串傳遞給OnMenuChange ,或者可以對App組件進行如下更改:

import PeopleApp from './PeopleApp';
import PlacesApp from './PlacesApp';

const APPS_BY_NAME = { PeopleApp, PlacesApp };

class App extends Component {
 render() {
    return (
      // ...
      <Container App={APPS_BY_NAME[this.state.currentApp]}/>
      // ...
    );
  }
}

暫無
暫無

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

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