Junius L
Junius L

Reputation: 16122

How to convert string to jsx in react native

I'm trying to display javascript string as jsx, it seems there's no way of display a string as jsx in react native, e.g. const test = '<Text>hello</Text>' render() { return ({test})}.

Given the following string

const svg = '<Svg.G fill="none" fill-rule="evenodd"> <Svg.Path fill="none" d="M0 0h24v24H0z"/> <Svg.Path stroke="#333" stroke-linecap="round" stroke-linejoin="round" d="M3.5 12.5h17v9h-17zM13.5 12.5v9M10.5 12.5v9M1.883 9.602l18.353-4.918.776 2.898L2.66 12.5z"/> <Svg.Path stroke="#333" stroke-linejoin="round" d="M6 6.857c.957.553 4.675.393 4.675.393S8.957 3.945 8 3.393a2 2 0 1 0-2 3.465zM15.296 4.366c-.546.956-3.852 2.674-3.852 2.674s-.164-3.718.388-4.674a2 2 0 1 1 3.464 2z"/> <Svg.Path stroke="#333" stroke-linecap="round" stroke-linejoin="round" d="M12.508 6.755l.777 2.897M9.61 7.531l.776 2.899"/></Svg.G>';

Then I want render it like the following

render() {
    return (
      <View>
        <Svg>
          {svg}
        </Svg>
      </View>
    );
}

This renders nothing, How can I render this string, or maybe I should turn the string into an array and render it as an array?

Upvotes: 6

Views: 7692

Answers (3)

abhiburk
abhiburk

Reputation: 2310

Well we could do this using import react-jsx-parser Added a line to filter out the lines and spaces as parser throws an error when their is space in the SVG code

Eg.

    var svg = `<Svg
    width={286}
    height={335}
    viewBox="0 0 286 335"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
    {...props}
    >
    <Path
      d="M63.763 25.066h17.72L107.542 1l14.593 16.741L248.258 32.39V140.16L284.74 257.35c-3.822 3.488-20.013 15.486-54.202 35.575-51.7 25.112-174.419 37.668-229.315 40.807l11.465-193.571c5.56.698 23.557 1.675 51.075 0 34.398-2.092 37.525 2.093 43.779-15.694 6.254-17.788-6.254-35.576-13.55-49.178-5.838-10.882-22.585-14.997-30.229-15.695V25.065z"
      fill="#F8F9F8"
      stroke="#22223B"
      strokeOpacity={0.8}
      strokeWidth={1.06988}
      strokeLinecap="round"
      strokeDasharray="6.42 6.42"
    />
    <Path
    onPress={handleOnPress}
      transform="rotate(3.757 16.59 146.446)"
      fill="#9A8C98"
      fillOpacity={0.22}
      d="M16.5894 146.446H40.5513V192.058H16.5894z"
    />
  </Svg>`
    svg = svg.replace(/\n/g, ' ').replace(/\>[\t ]+\</g, "><");
    return (
        <JsxParser
            components={{ Svg, Path }}
            renderInWrapper={false}
            bindings={{
                foo: 'foo',
                handleOnPress: () => alert('sasas'),
            }}
            blacklistedAttrs={[]} // this line should fix your issue
            jsx={svg}
        />
    );

Upvotes: 1

Oleksandr Blyzniuk
Oleksandr Blyzniuk

Reputation: 556

It's not an answer to your question, but maybe it helps you to figure out how to do what you want. I strongly not recommend using this approach ;)

So you can't just use eval for this string because you need to convert jsx to js. Babel doing it for us on building stage, but you can parse a string and convert it to React.createElement shape.

It will work only if you know what format of string with components you receive

I provide example only for your example (<Text>hello</Text>) because it is much easier, but it'll help you get an idea.

import React, { PureComponent } from 'react';
import RN, { View } from 'react-native';

function mapStringToComponent(stringToRender) {
    const parseResult = stringToRender.match(/<([a-z]*)>(.*)<\/[a-z]*>/i);
     // result of this regex ["<Text>hello</Text>", "Text", "hello"]

    if (parseResult !== null) {
      const [, compName, innerText] = parseResult;

      return React.createElement(
        RN[compName],
        null, // here may be an object with attributes if your node has any
        innerText,
      );
    }

    return null;
}


export default class MyDynamicComponent extends PureComponent {
  render() {
    const component = mapStringToComponent('<Text>hello</Text>');

    return (
      <View>
       {component}
      </View>
    );
  };
}

Here you can check how should looks your converted svg string: babel link

I've tried to google some lib that can do it for you but hasn't found any. Maybe I'm bad at googling :)

Upvotes: 10

Andr&#233; Abboud
Andr&#233; Abboud

Reputation: 2030

i saved the svg const you are trying to display as svg file and open it but it is blank

so try to fix it

the best way to display svg in react native is this way

import Image from 'react-native-remote-svg';
<View>
    <Image source={require('./assets/picture.svg')} />
</View>

Upvotes: 0

Related Questions