Render React Component assigned from an import to a variable.. how? - reactjs

So, I have a need for dynamic determination of which component to show.. so, for example. I have:
import Component1 from '..somepath/Component1'
import Component1 from '..somepath/Component2'
var P = {
red: Component1,
blue: Component2
}
render() {
var newComponent = P[color];
return (
<newComponent /> // not working
{newComponent} // not working
newComoponent // not working
)
}
this mapping could be huge, thus not doing a switch or if/else.
how do I get this to return in another component?

As per the convention the component name must be with the first letter capitalised:
render() {
var NewComponent = P[color];
return (
<NewComponent />
);
}
References:
https://facebook.github.io/react/docs/jsx-in-depth.html#html-tags-vs.-react-components

Related

How to save a component in a Const and render it?

I am new in react and basically I want that depending on a condition (I put something simple), a component that I have created called <Button> is rendered or the default <button> of HTML is rendered.
I don't know what I'm doing wrong, in any case it doesn't work, nothing is displayed.
This is my code:
import "./styles.css";
export const Button = ({ children }) => {
return <button>{children}</button>;
};
export default function App() {
let Component = "";
if (1 + 1 == 2) {
Component = <Button />;
} else {
Component = "button";
}
return <Component>I am a button</Component>;
}
This is my live code:
my live code
Change Component = <Button />; to Component = Button;.
Button is a function, <Button /> is an element. When you use <Component>I am a button</Component>, JSX expects Component to be a functional component or class component, not a JSX element.

Initializing state in React without constructor

I have a class component as shown below:
import React, { Component } from "react";
import Aux from "../../../hoc/Auxilary/Auxilary";
import ComponentDetails from "./SideBarLayoutDetails";
import DropDownDetails from "../UI/DropDown/DropDownDetails";
import Row from "../UI/Row/Row";
import "./Layouts.css";
import Dropdown from "../UI/DropDown/DropDown";
import Calendar from "../UI/Calendar/Calendar";
class SideBarLayout extends Component {
state = {
isActive: Array(DropDownDetails.length),
isDateActive: false,
}
DropDownArrowHandler = (index) =>
{
}
render()
{
const calendar = this.state.isDateActive ? <Calendar />:null;
return <Aux>
<div className = "SideBar-Central">
<Row Elems = {ComponentDetails.TopHeaders.elements}
Container = {ComponentDetails.TopHeaders.container}
/>
<Dropdown Elems = {DropDownDetails[0].DateFilter}
Container = {DropDownDetails[0].DateFilterContainer}
/>
{calendar}
</div>
</Aux>
}
}
export default SideBarLayout;
I want to initialize this.state.isActive in a loop fashion like this:
const initializedvalue = DropDownDetails.map(elem => elem.active);
and then use this initializedvalue to assign to this.state.isActive.
But I want to do this just when the component renders in the screen. What is the best way to do so? Should I use constructor? I don't prefer it as I get a warning using super(props). Please let me know the best way to do so. My end goal is to have a this.state.isActive array ready to be used in making the decisions about rendering the screen components.
First, forEach does not return any value as it is a void function. So try map function instead. This will return elements for which active is true (assuming active is a boolean type property in elem)
const initializedvalues = DropDownDetails.map(elem => elem.active);
Next, if you want to use this to set this.state.isActive after render, run it in componentDidMount(). Its a lifecycle function that runs after the initial render is done.

String from mobx store used as a react component name?

Using a map feels a bit repetative.
Any way to render react component using string passed down from mobx?
because when i have like 20 different dynamic components its quickly getting messy and repetative.
currently I'm using:
function ParentComponent(){
const compNames = {
component1: <component1/>,
component2: <component2/>,
}
const component = compNames[store.name];
return(
<div>
<MyComponentName type={type}/>
</div>
)
}
is anything shorter possible? for example
function ParentComponent(){
const {name: MyComponentName, type } = store
return(
<div>
<MyComponentName type={type}/>
</div>
)
}
the Parent component then imported into the index page.
// MobX store
import UserList from "./UserList";
import UserView from "./UserView";
#observable
component = {
"user-list": UserList,
"user-view": UserView
};
// observer component
#observer function UserComponent({type}) {
const Component = store.component[type];
return <Component />;
}
// display the component
<UserComponent type="user-list" />

Dynamically adding components in react

I need to add components by rendering it in react:
<componentName ..... />
However, the name of component is not known and coming from a variable.
How I can render that?
You will need to store references to the dynamic components:
import ComponentName from 'component-name'
class App extends Component {
constructor(props) {
super(props)
this.components = {
'dynamic-component': ComponentName
}
}
render() {
// notice capitalization of the variable - this is important!
const Name = this.components[this.props.componentName];
return (
<div>
<Name />
</div>
)
}
};
render(<App componentName={ 'dynamic-component' } />, document.getElementById('root'));
See the react docs for more info.
You can create a file that exports all the different components
// Components.js
export Foo from './Foo'
export Bar from './Bar'
then import them all
import * as Components from './Components'
then you can dynamically create them based on a variable/prop:
render() {
// this.props.type = 'Foo'
// renders a Foo component
const Component = Components[this.props.type];
return Component && <Component />;
}
Okay, for me this worked:
import {Hello} from 'ui-hello-world';
let components = {};
components['Hello'] = Hello;
export default components;
and then in my class:
import customComps from '.....json';
....
let Component = Custom.default[customComps.componentName];
return (
<Component

React Loading a Dynamic Template using JSX & ES6

I'm pretty new to React, coming from an angular world. I have a scenario where I need to dynamically load a component give a searchType prop. The end user will have a dropdown of searchTypes they can pick from, this prop is passed in after they click the submit button.
I have a SearchResults component defined, which should dynamically load the appropriate component depending on the value of this.props.searchType.name
import React, { findDOMNode, Component, PropTypes } from 'react';
import Material from './Material'; // Material Search Results Component
import Vendor from './Vendor'; // Vendor Search Results Component
export default class SearchResults extends Component {
constructor(props){
super(props);
}
// searchType = {
// name: 'Material',
// id: 'MATERIAL'
// }
render() {
const { searchType, items, itemsCount } = this.props;
var ComponentName = searchType.name;
return (
<div className='row'>
<h1>Search Results ({items.length}/{itemsCount})</h1>
<ComponentName items={items} />
</div>
);
}
}
SearchResults.propTypes = {
items: PropTypes.array.isRequired
};
Now, this seems to partially work as when using the React Dev Tools in chrome I can see the provider/component show up in the DOM.. but it doesn't render.
I'm just not sure where to go next from here, or if i'm doing something wrong.
You're trying to use a string instead of the actual class. I think you want something like this:
var searchTypes = {
Material,
Vendor,
};
// ...
var Component = searchTypes[searchType.name];
return (
<div className='row'>
<h1>Search Results ({items.length}/{itemsCount})</h1>
<Component items={items} />
</div>
);
Here's a simple example.
You could try a switch statement.
render() {
//...
var component;
switch(searchType.name){
case "material":
component = <Material items={items} />
case "vendor":
component = <Vendor items={items} />
}
return (
//...
{component}
)
}

Resources