Using for loops and switch cases in React to dynamically render different components
我正在尝试使用 React JSX 中的 switch case 有条件地渲染组件。我正在尝试构建从特定 json 结构读取并呈现数据的东西。由于可能有许多不同的组件和数据,我试图动态呈现它。请参阅下面的代码,我没有收到任何错误,但组件没有被渲染。在我的 html 里面,我只能看到 .这意味着循环不工作。我尝试在 vanilla JS 中使用相同的循环并且它有效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | var myPackage = [{ sectionInfo:[{ elementType: 1, text:"This is text from element type 1" }] }, { sectionInfo:[{ elementType: 2, text:"This is text from element type 2" }] }]; var App = React.createClass({ render: function(){ var elements = []; elements = myPackage.map(function(myObj){ myObj.sectionInfo.map(function(myObj1){ switch(myObj1.elementType){ case 1: return( <Component1 text = {myObj1.text}/> ); break; case 2: return( <Component2 text = {myObj1.text}/> ) break; } }) }); return( {elements} ) } }); var Component1 = React.createClass({ render:function(){ return( {this.props.text} ) } }); var Component2 = React.createClass({ render:function(){ return( {this.props.text} ) } }); ReactDOM.render(<App/>,document.getElementById('container')); |
编辑:对代码做了一些补充,现在我面临一个新问题。这是新代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | var App = React.createClass({ render: function(){ var elements = []; elements = myPackage.map(function(myObj){ return( myObj.sectionInfo.map(function(myObj1){ switch(myObj1.elementType){ case 1: return( <Component1 text = {myObj1.text}/> ); break; case 2: return( <Component2 text = {myObj1.text}/> ) break; } } ) }); return( {elements} ) } }); |
我想每次都在一个 div 中渲染。所以如果一个部分有超过 3 个元素,那么所有 3 个元素都必须在一个 div 内。
在 JSX 中做一个 switch case 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | {{ sectionA: ( <SectionAComponent /> ), sectionB: ( <SectionBComponent /> ), sectionC: ( <SectionCComponent /> ), default: ( <SectionDefaultComponent /> ) }[section]} |
对于内联/未创建新函数,可以这样使用
1 2 3 4 5 6 7 8 | {(() => { switch (myObj1.elementType) { case 'pantulan': return <Component1 text = {myObj1.text} key={ key } /> default : null } })()} |
您应该从第一个
的结果
1 2 3 4 5 | var elements = myPackage.map(function(myObj){ return myObj.sectionInfo.map(function(myObj1) { // ... }); }); |
更新:
根据您的新更新,您可以像这样更改您的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | var App = React.createClass({ section: function(myObj, parentIndex) { return myObj.sectionInfo.map(function(myObj1, index) { const key = parentIndex + '.' + index; switch(myObj1.elementType) { case 1: return <Component1 text = {myObj1.text} key={ key } /> case 2: return <Component2 text = {myObj1.text} key={ key } /> } }); }, render: function() { var elements = myPackage.map(function(myObj) { return { this.section(myObj, index) } }, this); return { elements } ; } }); |
React 推荐的方式:React Docs
1 2 3 4 5 6 7 8 9 10 | const components = { photo: PhotoStory, video: VideoStory }; function Story(props) { // Correct! JSX type can be a capitalized variable. const SpecificStory = components[props.storyType]; return <SpecificStory story={props.story} />; } |
正如 Alexander T 的回答中所述,您缺少返回值,但我也建议为您的每个元素添加一个键。 React 的差异算法取决于此值,您可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | render: function(){ var elements = myPackage.map(function(myObj, pIndex){ return myObj.sectionInfo.map(function(myObj1, sIndex){ var key = pIndex + '.' + sIndex; switch(myObj1.elementType) { case 1: return( <Component1 key={key} text={myObj1.text}/> ); case 2: return( <Component2 key={key} text={myObj1.text}/> ) } }) }); return( {elements} ) } |
阅读此处了解更多信息:https://facebook.github.io/react/docs/multiple-components.html#dynamic-children