简体   繁体   中英

React Dynamic Component Naming

I'm new to React so please have mercy.

I've also read all of the threads on this, React / JSX Dynamic Component Name and React/JSX dynamic component names in particular. The solutions did not work.

I'm using a tab style interface where a user selects a tab and the appropriate content loads. A parent component stores the tab's content state, passes the corresponding props to the content child. This child then loads the correct content component (as its own child).

var TabbedContent = React.createClass({

loadMenu: function() {
    var menus=this.props.carDivState.vehicleDetailState;
    for (key in menus) {
        if (menus.hasOwnProperty(key)) {
            if (menus[key]) { 
                var Component='TabbedContent'+key;
                return <Component />;
            }         
        }
    }
},

render: function() {
    return (
        <div className="TabbedContent">
            <div className="contentWrapper">
                {this.loadMenu()}
            </div>
        </div>
    )
}

});

loadMenu loops through the props until it finds a true prop. It then returns that key (for instance "Overview") and creates a variable (eg Component='TabbledContentOverview').

However, my code returns an HTML tag <tabbedcontentoverview></tabbedcontentoverview>

Question

How do I get React to return the React component instead of an HTML tag? I appear to be using the correct capitalized naming conventions. I've read the Facebook docs. I just don't get it.

You need to have a reference to an actual class in order to create an element from it (in JS or JSX).

Hold a map of keys to React classes (ie tabbedChildren ), and just create this element using the JS API:

var childComponent = tabbedChildren[key] 
return React.createElement(childComponent)

https://facebook.github.io/react/docs/top-level-api.html

First, if you are using Bootstrap for your app, I'd suggest that you use react-bootstrap`s tab . If you are not, I would suggest that you at least take a look at the implementation of their TabPane and TabbedArea .

Here's an example of how it looks like in your app:

const tabbedAreaInstance = (
  <TabbedArea defaultActiveKey={2}>
    <TabPane eventKey={1} tab='Tab 1'>TabPane 1 content</TabPane>
    <TabPane eventKey={2} tab='Tab 2'>TabPane 2 content</TabPane>
    <TabPane eventKey={3} tab='Tab 3' disabled>TabPane 3 content</TabPane>
  </TabbedArea>
);

React.render(tabbedAreaInstance, mountNode);

Now, back to your question, if you want to create a component by name, just call React.createElement from inside your loadMenu :

loadMenu: function() {
    var menus=this.props.carDivState.vehicleDetailState;
    for (key in menus) {
        if (menus.hasOwnProperty(key)) {
            if (menus[key]) { 
                return React.createElement('TabbedContent'+key);
            }         
        }
    }
}

https://github.com/vasanthk/react-bits/blob/master/patterns/30.component-switch.md

import HomePage from './HomePage.jsx';
import AboutPage from './AboutPage.jsx';
import UserPage from './UserPage.jsx';
import FourOhFourPage from './FourOhFourPage.jsx';

const PAGES = {
  home: HomePage,
  about: AboutPage,
  user: UserPage
};

const Page = (props) => {
  const Handler = PAGES[props.page] || FourOhFourPage;

  return <Handler {...props} />
};

// The keys of the PAGES object can be used in the prop types to catch dev-time errors.
Page.propTypes = {
  page: PropTypes.oneOf(Object.keys(PAGES)).isRequired
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM