【发布时间】:2017-10-30 13:20:00
【问题描述】:
我正在使用ReactDOM.render() 来渲染我创建的组件。由于实现的细节,该组件相当复杂,但我可以轻松地渲染它iff 我避免使用 JSX 语法。但是,如果我使用 JSX,则根本无法渲染组件,并且会出现以下错误:
TypeError: _this2.props.children.forEach 不是函数
我的代码可以在下面看到(我还收到了一些我还没有解决的警告,所以你可以暂时忽略这些)。请记住,组件的 HTML 结构非常严格(由于我使用的 CSS 框架)并且无法更改。有没有办法使用 JSX 来实现相同的结果,如果是,我做错了什么?
// This function was based on this answer: https://stackoverflow.com/a/10734934/1650200
function generateUniqueId() {
// always start with a letter (for DOM friendlyness)
var idstr = String.fromCharCode(Math.floor((Math.random() * 25) + 65));
do {
// between numbers and characters (48 is 0 and 90 is Z (42-48 = 90)
var ascicode = Math.floor((Math.random() * 42) + 48);
if (ascicode < 58 || ascicode > 64) {
// exclude all chars between : (58) and @ (64)
idstr += String.fromCharCode(ascicode);
}
} while (idstr.length < 32);
return (idstr);
}
// Technically this is not exactly a component, but I use it as such to make things simpler.
class Tab extends React.Component {
render() {
return React.createElement('div', {}, this.props.children);
}
}
// This is my Tabs component
class Tabs extends React.Component {
// In the constructor, I take all children passed to the component
// and push them to state with the necessary changes made to them.
constructor(props) {
super(props);
var state = {
group: 'tab_group_' + generateUniqueId(),
children: []
}
this.props.children.forEach(
function(child) {
if (!child instanceof Tab) {
throw "All children of a 'Tabs' component need to be of type 'Tab'. Expected type: 'Tab' Found Type: '" + child.class + "'";
return;
}
var tab = Object.assign({}, child);
tab.internalId = 'tab_' + generateUniqueId();
state.children.push(tab);
}
);
this.state = state;
}
// When rendering, I don't render the children as needed, but I create
// the structure I need to use for the final result.
render() {
var childrenToRender = [];
var groupName = this.state.group;
this.state.children.forEach(function(tab) {
childrenToRender.push(
React.createElement(
'input', {
type: 'radio',
name: groupName,
id: tab.internalId,
checked: true,
'aria-hidden': 'true'
}
)
);
childrenToRender.push(
React.createElement(
'label', {
'htmlFor': tab.internalId,
'aria-hidden': 'true'
},
'demo-tab'
)
);
childrenToRender.push(React.createElement('div', {}, tab.props.children));
});
return React.createElement('div', {
'className': 'tabs'
}, childrenToRender);
}
}
// This works fine
ReactDOM.render(
React.createElement(Tabs, {}, [React.createElement(Tab, {}, 'Hello world')]),
document.getElementById('root')
);
// This fails with the error mentioned above
// ReactDOM.render(
// <Tabs>
// <Tab>Hello, world!</Tab>
// </Tabs>,
// document.getElementById('root')
// );
<link rel="stylesheet" href="https://gitcdn.link/repo/Chalarangelo/mini.css/master/dist/mini-default.min.css">
<script src="https://unpkg.com/react@latest/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@latest/dist/react-dom.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<div id="root"></div>
更新:只有当我实际上只将一个 <Tab> 传递给 <Tabs> 时才会发生这种情况,因为它的处理方式。例如,如果我使用以下代码,我可以使用 JSX 来呈现组件及其内容:
ReactDOM.render(
<Tabs>
<Tab>Hello, world!</Tab>
<Tab>Hello, world!</Tab>
</Tabs>,
document.getElementById('root')
);
【问题讨论】:
-
可能没有 forEach。反正孩子们算什么。也许这将有助于如何访问它。 facebook.github.io/react/docs/jsx-in-depth.html找
Functions as children
标签: javascript reactjs react-dom