我有一个菜单组件,应该在另一个容器组件中动态加载元素。但是,子元素永远不会被渲染。
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,
}
]
}
];
然后将该列表传递到菜单中,该菜单现在将'type'传递回而不是名称。这样做效果更好,因为名称现在可以包含空格。
答案 0 :(得分:1)
我认为问题可能是您的state
对象在第一次渲染发生时未定义,然后阻止对它进行任何类型的更新。我可能只是将它设置为一个空对象来初始化它。
class MyComponent extends Component {
state = {
App: null
}
}
答案 1 :(得分:1)
让我们考虑一下JSX的这一点:
<this.props.App />
⬇
React.createElement(this.props.App, null)
...现在查看React.createElement
的内容。来自the docs:
的createElement()
React.createElement( type, [props], [...children] )
创建并返回给定类型的新React元素。类型 参数可以是标签名称字符串(例如
'div'
或'span'
)或React组件类型(类或函数)。
从它的外观来看,代码中的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]}/>
// ...
);
}
}