Use Babel Transform inside of React code

和自甴很熟 提交于 2019-12-12 17:13:08

问题


I'm trying to convert a string to valid JSX code, and then inject it into my React component.

const babel = require('babel-core')
let result = eval(babel.transform('<p className="greeting">Hello</p>').code)

But am getting hit with a wall of errors, because I'm trying to use Babel in the browser:

ERROR in ./~/babel-core/lib/api/node.js
Module not found: Error: Can't resolve 'fs' in '/Users/ben/Desktop/Work/code/ru-coding-challege/node_modules/babel-core/lib/api'
 @ ./~/babel-core/lib/api/node.js 72:10-23
 @ ./~/babel-core/index.js
 @ ./src/js/containers/app-container.js
 @ ./src/js/index.js
 @ multi (webpack)-dev-server/client?http://localhost:3000 ./src/js/index.js

...more similar errors

Yes, I know creating code from a string and injecting it is frowned upon, but D3 creates elements dynamically (i.e. you can't write them declaratively) For example: axes whose values and number of ticks change based on the data. I've successfully changed the D3 axes into JSX with htmltojsx but that returns a String. I need to turn that String into valid JSX components that I can inject into my code.

EDIT: As Michael Lyons states below, I could just use dangerouslySetInnerHTML, but I am trying to avoid this option unless everything else doesn't work. Trying to stay within the React paradigm as much as possible.

Here's how my component's render method would look:

<svg width='100%' height='600'>
  <g transform='translate(50, 50)'>
    <path d='...' className='path-0'></path>
  </g>
  {/* Insert JSX elements here. e.g. axes below */}
  {axes}
</svg>

And here is my webpack.config.js

const CopyWebpackPlugin = require('copy-webpack-plugin')
const path = require('path')
const webpack = require('webpack')

module.exports = {
  entry: './src/js/index.js',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].bundle.js',
  },
  devServer: {
    inline: true,
    contentBase: path.join(__dirname, 'dist'),
    port: 3000
  },
  plugins: [
    new CopyWebpackPlugin([
      { from: 'src/html/index.html' }
    ]),
    new webpack.DefinePlugin({
      IN_BROWSER: true,
    }),
  ],
  module: {
    loaders: [
      {
        test: /\.scss$/,
        exclude: /(node_modules)/,
        loader: 'style-loader!css-loader!sass-loader'
      },
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015', 'react']
        }
      }
    ]
  }
}

回答1:


Instead of translating HTML to JSX, then rendering with babel in your code while on the client, you could render that html directly through your React component.

Facebook's DOM element implementation has built in functionality for this use-case, and you are right it is generally frowned upon for security reasons because it opens up vulnerabilities to cross-site scripting.

Facebook has even labeled it "dangerouslySetInnerHTML" to remind devs that this is dangerous.

So if you have HTML in a string format, you can render that in JSX in a manner such as this:

getMarkup() {
  return { __html: '<p class="greeting">Hello</p>' }
}
render() {
  return <div dangerouslySetInnerHTML={this.getMarkup()} />;
}

This comes straight from the React DOM elements documentation here: Docs

This method should also allow you to bypass having to convert your d3 output to JSX

Edit: Introductory sentence



来源:https://stackoverflow.com/questions/43667083/use-babel-transform-inside-of-react-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!