我想用2个组件创建一个简单的流程。第一个组件被渲染,我单击它上面的一个按钮,这个动作渲染第二个组件。单击第二个组件中的按钮,它应该切换回第一个组件,但是发生错误:
警告:React.createElement:type不应为null,未定义, 布尔值或数字。它应该是一个字符串(对于DOM元素)或a ReactClass(用于复合组件)。检查渲染方法
exports
。warning @ react.js:20728ReactElementValidator.createElement @ react.js:9853t.exports.React.createClass.render @ bundle.js:1ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext @ react.js:6330ReactCompositeComponentMixin._renderValidatedComponent @ react.js:6350wrapper @ react.js:12868ReactCompositeComponentMixin._updateRenderedComponent @ react.js:6303ReactCompositeComponentMixin._performComponentUpdate @ react.js:6287ReactCompositeComponentMixin.updateComponent @ react.js:6216wrapper @ react.js:12868ReactCompositeComponentMixin.performUpdateIfNecessary @ react.js:6164ReactReconciler.performUpdateIfNecessary @ react.js:13667runBatchedUpdates @ react.js:15356Mixin.perform @ react.js:17245Mixin.perform @ react.js:17245assign.perform @ react.js:15313flushBatchedUpdates @ react.js:15374wrapper @ react.js:12868Mixin.closeAll @ react.js:17311Mixin.perform @ react.js:17258ReactDefaultBatchingStrategy.batchedUpdates @ react.js:8842batchedUpdates @ react.js:15321ReactEventListener.dispatchEvent @ react.js:10336 react.js:20250未捕获错误:不变违规:元素类型无效:预期 字符串(用于内置组件)或类/函数(用于复合 组件)但得到:对象。检查渲染方法
exports
。invariant @ react.js:20250instantiateReactComponent @ react.js:18268ReactCompositeComponentMixin._updateRenderedComponent @ react.js:6312ReactCompositeComponentMixin._performComponentUpdate @ react.js:6287ReactCompositeComponentMixin.updateComponent @ react.js:6216wrapper @ react.js:12868ReactCompositeComponentMixin.performUpdateIfNecessary @ react.js:6164ReactReconciler.performUpdateIfNecessary @ react.js:13667runBatchedUpdates @ react.js:15356Mixin.perform @ react.js:17245Mixin.perform @ react.js:17245assign.perform @ react.js:15313flushBatchedUpdates @ react.js:15374wrapper @ react.js:12868Mixin.closeAll @ react.js:17311Mixin.perform @ react.js:17258ReactDefaultBatchingStrategy.batchedUpdates @ react.js:8842batchedUpdates @ react.js:15321ReactEventListener.dispatchEvent @ react.js:10336
第一部分:
/** @jsx React.DOM */
var Second = require('components/second/view.jsx');
module.exports = React.createClass({
handlerClick: function () {
ReactDOM.render(
<Second />,
document.getElementById("app-container")
)
},
render: function() {
return (
<input type="button" value="COMPONENT 1" onClick={this.handlerClick} />
)
}
});
第二部分:
/** @jsx React.DOM */
var First = require('components/first/view.jsx');
module.exports = React.createClass({
handlerClick: function () {
ReactDOM.render(
<First />,
document.getElementById("app-container")
)
},
render: function() {
return (
<input type="button" value="COMPONENT 2" onClick={this.handlerClick} />
)
}
});
Index.js
ReactDOM.render(
<div>
<First />
</div>,
document.getElementById("app-container")
);
答案 0 :(得分:6)
您只能在挂载应用程序时调用ReactDOM.render()
。安装后,您再也不会在同一个挂载点上再次调用ReactDOM.render()
。 [*见下面的更新。]
请记住,您的视图是道具和州的功能。要更改视图,请触发状态更改。
我建议这样的事情:
var Parent = React.createClass({
getInitialState: function () {
return {
active: 'FIRST'
};
},
handleClick: function () {
var active = this.state.active;
var newActive = active === 'FIRST' ? 'SECOND' : 'FIRST';
this.setState({
active: newActive
});
},
render: function () {
var active = this.state.active;
return (
<div>
{active === 'FIRST' ? (
<First />
) : active === 'SECOND' ? (
<Second />
) : null}
<button type="button" onClick={this.handleClick}>
Toggle
</button>
</div>
);
}
});
并将Parent设为根节点。即。
ReactDOM.render(<Parent />, document.getElementById('app-container'));
更新:我知道您可以致电ReactDOM.render()
multiple times on the same mount point。这通常与您初始化应用程序的位置相同。不过,你肯定不会从React组件中调用ReactDOM.render()
。
答案 1 :(得分:2)
这是创建SwitchComponents
组件的非常简单的解决方案:
// SwitchComponents.js:
import React from 'react';
export default function SwitchComponents({ active, children }) {
// Switch all children and return the "active" one
return children.filter(child => child.props.name == active)
}
并将其导入您的应用程序:
// App.js
import SwitchComponents from './components/SwitchComponents';
export default function App() {
const [activeComponent, setActiveComponent] = useState("questions")
return (
<SwitchComponents active={activeComponent}>
<Home name="home" />
<Instructions name="instructions" />
<FileboxContainer name="filebox" />
<Questions name="questions" />
</SwitchComponents>
)
}
答案 2 :(得分:1)
三元运算符将被简单替换,完整答案将如下:
/** @jsx React.DOM */
var Parent = React.createClass({
getInitialState: function () {
return {
active: 'FIRST'
};
},
handleClick: function () {
var active = this.state.active;
var newActive = active === 'FIRST' ? 'SECOND' : 'FIRST';
this.setState({
active: newActive
});
},
render: function () {
var active = this.state.active;
return (
<div>
{(active === 'FIRST') && <First /> }
{(active === 'SECOND') && <Second /> }
<button type="button" onClick={this.handleClick}>
Toggle
</button>
</div>
);
}
});
ReactDOM.render(<Parent />, document.getElementById('app-container'));
休息将是一样的。
答案 3 :(得分:0)
挂钩版本(反应16.8 +):
最低版本。
import React, { useState } from 'react';
export default function App() {
const [toggle, setToggle] = useState(true);
const toggleChecked = () => setToggle(toggle => !toggle);
return (
<div>
{toggle && <First /> }
{!toggle && <Second /> }
<button type="button" onClick={this.toggleChecked}>
Toggle
</button>
</div>
);
}