I need help trying to dynamically return/render a custom component in my react native app.
My goal is to use a variable to render a component, instead of that component's original name.
In my react native code, I have 4 "character" components which take the exact same props. Any one of these might need to be rendered based on my user's interaction, so I want to clean up my code by only writing the component block once.
My problem is that to make this work right now I have a switch/case block taking the prop and returning the correct component. This means I have a lot of repeating code which I'd like to remove, but I keep getting the same error:
View config getter callback for component [MY COMPONENT NAME] must be a function (received 'undefined')
My full code is below, what am I doing wrong?
import React, { } from 'react';
import {
View,
} from "react-native";
// My custom components
import Larry from './characters/larry';
import Jane from './characters/jane';
import Reginald from './characters/reginald';
import Amy from './characters/amy';
const CharacterFactory = (props) => {
// I WANT TO DO IT THIS WAY BUT IT DOES NOT WORK AND RESULTS IN AN ERROR:
// View config getter callback for component 'Larry' must be a function (received 'undefined')
const FactoryOutput = props.character;
return (
<FactoryOutput
top={props.top}
bottom={props.bottom}
shoes={props.shoes}
/>
);
// THIS APPROACH WORKS BUT IT IS TOO LONG AND INEFFICIENT AS MORE CHARACTERS GET ADDED
switch (props.character) {
case 'Larry':
return (
<Larry
top={props.top}
bottom={props.bottom}
shoes={props.shoes}
/>
);
break;
case 'Jane':
return (
<Jane
top={props.top}
bottom={props.bottom}
shoes={props.shoes}
/>
);
break;
case 'Reginald':
return (
<Reginald
top={props.top}
bottom={props.bottom}
shoes={props.shoes}
/>
);
break;
case 'Amy':
return (
<Amy
top={props.top}
bottom={props.bottom}
shoes={props.shoes}
/>
);
break;
default:
break;
}
}
export default CharacterFactory;
OP here, I figured it out and wanted to leave the answer here for future readers.
First you have to create a const object of all imported components that you want to dynamically render. This has to be outside of the main component block.
const characters = {
Larry,
Jane,
Reginald,
Amy,
};
Then inside your main component, you create a const for your target import by referencing the array you created earlier.
const FactoryOutput = characters[props.character];
And finally you can write a single block of code which will dynamically render the imported component based on a prop value. No more switch/case statements.
<FactoryOutput
top={props.top}
bottom={props.bottom}
shoes={props.shoes}
/>
Here's the original code modified with the solution:
import React, {} from 'react';
import {
View,
} from "react-native";
// My custom components
import Larry from './characters/larry';
import Jane from './characters/jane';
import Reginald from './characters/reginald';
import Amy from './characters/amy';
const characters = {
Larry,
Jane,
Reginald,
Amy,
};
const CharacterFactory = (props) => {
const FactoryOutput = characters[props.character];
return (
<FactoryOutput
top={props.top}
bottom={props.bottom}
shoes={props.shoes}
/>
);
}
export default CharacterFactory;