问题
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