admin管理员组

文章数量:1026989

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 ponent 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 ponent stores the tab's content state, passes the corresponding props to the content child. This child then loads the correct content ponent (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 (e.g. Component='TabbledContentOverview').

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

Question

How do I get React to return the React ponent 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.

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 ponent 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 ponent stores the tab's content state, passes the corresponding props to the content child. This child then loads the correct content ponent (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 (e.g. Component='TabbledContentOverview').

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

Question

How do I get React to return the React ponent 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.

Share Improve this question edited May 23, 2017 at 12:30 CommunityBot 11 silver badge asked Aug 12, 2015 at 20:14 D. WalshD. Walsh 1,9931 gold badge22 silver badges24 bronze badges 3
  • I'd find another way of doing it, dynamic like that seems like a recipe for disaster... Why not use props like <TabbedContent type={key}/>? – elclanrs Commented Aug 12, 2015 at 20:16
  • As I understand your solution, you would pass the key as a prop and then store all of the potential tabbed content in the same ponent? I worry that as the sections scale, I'll be left with one giant and unwieldy ponent. What am I missing or why am I wrong? Thank you for taking the time to reply! – D. Walsh Commented Aug 12, 2015 at 20:33
  • That was my suggestion, but I guess it depends on how many alternatives you need. In any case, you can build dynamic ponents, after all, JSX is "just JavaScript"; there is a displayName property that you can use to create classes dynamically with React.createClass – elclanrs Commented Aug 12, 2015 at 20:45
Add a ment  | 

3 Answers 3

Reset to default 4

https://github./vasanthk/react-bits/blob/master/patterns/30.ponent-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
};

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 ponent 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);
            }         
        }
    }
}

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 (i.e 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

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 ponent 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 ponent stores the tab's content state, passes the corresponding props to the content child. This child then loads the correct content ponent (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 (e.g. Component='TabbledContentOverview').

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

Question

How do I get React to return the React ponent 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.

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 ponent 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 ponent stores the tab's content state, passes the corresponding props to the content child. This child then loads the correct content ponent (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 (e.g. Component='TabbledContentOverview').

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

Question

How do I get React to return the React ponent 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.

Share Improve this question edited May 23, 2017 at 12:30 CommunityBot 11 silver badge asked Aug 12, 2015 at 20:14 D. WalshD. Walsh 1,9931 gold badge22 silver badges24 bronze badges 3
  • I'd find another way of doing it, dynamic like that seems like a recipe for disaster... Why not use props like <TabbedContent type={key}/>? – elclanrs Commented Aug 12, 2015 at 20:16
  • As I understand your solution, you would pass the key as a prop and then store all of the potential tabbed content in the same ponent? I worry that as the sections scale, I'll be left with one giant and unwieldy ponent. What am I missing or why am I wrong? Thank you for taking the time to reply! – D. Walsh Commented Aug 12, 2015 at 20:33
  • That was my suggestion, but I guess it depends on how many alternatives you need. In any case, you can build dynamic ponents, after all, JSX is "just JavaScript"; there is a displayName property that you can use to create classes dynamically with React.createClass – elclanrs Commented Aug 12, 2015 at 20:45
Add a ment  | 

3 Answers 3

Reset to default 4

https://github./vasanthk/react-bits/blob/master/patterns/30.ponent-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
};

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 ponent 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);
            }         
        }
    }
}

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 (i.e 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

本文标签: javascriptReact Dynamic Component NamingStack Overflow