I'm trying to generate UI dynamically in react native from a String fetched from an API. I don't quite get why eval() is not working in this example:
<View style={{flex:1}}>
{eval('React.createElement(Text, { style: styles.highlight }, `This is my text`)')}
</View>
Error:
ReferenceError: can't find variable: React
Even though I'm getting this error, if I run the same code directly without eval it works perfectly:
<View style={{flex:1}}>
{React.createElement(Text, { style: styles.highlight }, `This is my text`)}
</View>
No error and the text "This is my text" is rendered properly.
Any idea why this is happening?
I'm trying to generate UI dynamically in react native from a String fetched from an API. I don't quite get why eval() is not working in this example:
<View style={{flex:1}}>
{eval('React.createElement(Text, { style: styles.highlight }, `This is my text`)')}
</View>
Error:
ReferenceError: can't find variable: React
Even though I'm getting this error, if I run the same code directly without eval it works perfectly:
<View style={{flex:1}}>
{React.createElement(Text, { style: styles.highlight }, `This is my text`)}
</View>
No error and the text "This is my text" is rendered properly.
Any idea why this is happening?
Share Improve this question edited Sep 5, 2019 at 17:27 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Sep 2, 2019 at 16:02 Ismael Darwish MateosIsmael Darwish Mateos 811 silver badge4 bronze badges 9-
3
I'd guess that there's minification going on, so that although
React
is defined before the minifier runs, it's not defined at runtime later. You can check whether I'm correct by inspecting the code that's running at runtime, or by updating your second code block so that instead of theThis is my text
template literal you havetypeof React
. – T.J. Crowder Commented Sep 2, 2019 at 16:07 -
It's true,
<Text>{eval('typeof _React')}</Text>
outputs "undefined". I guess I need to first convert that javascript String with babel to something executable, but I'm not really sure how to do it :/ – Ismael Darwish Mateos Commented Sep 2, 2019 at 16:42 -
1
You have an errant
_
in your ment, hopefully not in your real code doing the test...? – T.J. Crowder Commented Sep 2, 2019 at 16:56 - Yeah, sorry about that. The code was actually without the "_". I'm not sure how to edit that ment – Ismael Darwish Mateos Commented Sep 3, 2019 at 9:49
-
1
You can't after five minutes, but no worries. :-) Converting the string with Babel probably won't help. If there's minifying/aliasing going on, two separate runs (one on your main code, another when you convert that string) won't necessarily use the same alias for
React
. You could find out what the alias is and, if it looks stable, use that alias, but really you want to avoid evaluating code from strings anyway wherever possible. – T.J. Crowder Commented Sep 3, 2019 at 9:54
1 Answer
Reset to default 6A solution could be to wrap the eval execution inside a function and copy each variable into this
.
The transpiler/minifier/uglifier won't change the names of the properties of any object, and also won't rename this
because it's a keyword.
So, something like this should work
import React from 'react';
import { Text } from 'react-native';
(function() {
this.React = React;
this.Text = Text;
eval('this.React.createElement(this.Text, {}, "This is my text")');
})();