I have svg icons These are <A/>
, <B/>
, <C/>
.
I want to use these icons in <MyButton>
.
This is how I am using it now.
MyButton.js
function MyButton(props) {
return (
<TouchableOpacity>
{props.icon}
<Text>{props.title}</Text>
</TouchableOpacity>
);
}
App.js
import A from "./A";
import B from "./B";
import C from "./C";
function App() {
return (
<MyButton icon={<A/>} title={'Example'} />
);
}
I want the icons to be selectable with string instead of sending them with props. How can I do that?
_App.js
function App() {
return (
<MyButton icon={"a"} title={'Example'} />
);
}
4
Answers
You can follow this approach. Creating an object of icons, then you can pass icon as string from props to MyButton Component.
Usage
Let me know in comments if it helps!
Solution 1
Solution 2
Your SVG icons are (very probably) React components. I’m afraid there is no (clean/reliable) way to access those components by a string, because they are basically a javascript function (or a "class"), and are not accessible via a string. (except if already mapped to some object, even if it’s the
window
object).string-to-object mapping in javascript
Accessing something "by string" in javascript means finding a string inside a collection, in some way or another, where the "collection" might be an object, an array, or even a string itself.
There is no javascript collection of your components per se, so to be able to select one component "by string", you need to create a collection first, i.e. some list of key-value pairs that associate a string to each component, as other answers already suggested, e.g.
Furthermore, as soon as a React component is "known" to javascript, it takes up memory space.
I.e. as soon as there is a javascript key-to-object mapping, that means that the objects exists from javascripts perspective, so if you have hundreds icons, and a mapping, then you have hundreds of components at once in the memory (while you probably only need a few at a time).
file system mapping
However, some libraries use specific file names, i.e. they use the file system as a "mapping" (i.e. the key is the file name, the value is the actual file data), and dynamically create an URL, e.g.
file system:
code:
The URL could be used to
fetch( url )
some image data, or as a source for an<img>
tag, or incorporated into the DOM in other, possibly weird ways. But they don’t use React components here.Build time
Other libraries might auto-map icon components to javascript identifiers with some build-time- or pre-build-tools, e.g. some script might read the contents of one specific folder, and even analyzing your code and finding icon names in it, and import only the used components.
After so many years working in
react-native
, here is the way I am handeling button icons:File structure
assets/A.tsx: auto generated by
SVGR
. Can be made manuallyassets/index.ts: auto generated by
SVGR
. Can be made manuallyButton.tsx
App.tsx
Hope it will help.