我正在使用这个库:html-to-react
,因为我发现可以将HTML字符串“编译”成React组件。
我们正在做一个基于小部件的系统,它们可能会随着时间的推移而改变(即添加/删除/更新等),因此我们计划将小部件HTML从数据库发送到前端,使用React完成。
我已经成功地使用HTML创建了一个简单的小部件,现在我正在尝试使这个小部件响应点击事件,所以我想添加来自HTML的onclick=method()
方法或来自React的onClick={method}
方法。然而,由于我在浏览器控制台中得到了这些错误,所以我无法获得所需的输出。
Warning: Invalid event handler property `onclick`. React events use the camelCase naming convention, for example `onClick`.
in label
in span
in div
Warning: Invalid event handler property `onclick`. Did you mean `onClick`?
in label
in span
in div
in DireccionComponent (at App.js:51)
in div (at App.js:50)
in GridItem (created by ReactGridLayout)
in div (created by ReactGridLayout)
in ReactGridLayout (at App.js:49)
in App (at index.js:11)
我使用的代码如下:
App.js
import React, { Component } from 'react';
import './App.css';
import DireccionComponent from './DireccionComponent.js';
class App extends Component {
render() {
return (
<DireccionComponent />
);
}
}
export default App;
DireccionComponent.js
import React, {Component} from 'react';
var ReactDOMServer = require('react-dom/server');
var HtmlToReactParser = require('html-to-react').Parser;
let htmlInput = ''
+ '<div>'
+ '<center><label className="title">Widget</label></center>'
+ '<span className="ui-float-label">'
+ '<label htmlFor="float-input" onClick={this.myFunction}>Hello</label>'
+ '</span>'
+ '</div>';
var htmlToReactParser = new HtmlToReactParser();
var reactElement = htmlToReactParser.parse(htmlInput);
var reactHtml = ReactDOMServer.renderToStaticMarkup(reactElement);
class DireccionComponent extends Component {
constructor(props) {
super (props);
this.myFunction = this.myFunction.bind(this);
}
render() {
return (
reactElement
)
}
myFunction() {
console.log('Hola');
alert("Hola");
}
}
export default DireccionComponent;
package.json
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"html-to-react": "^1.3.3",
"primereact": "^1.5.1",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-dom-server": "0.0.5",
"react-grid-layout": "^0.16.6",
"react-scripts": "1.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
使用上述库将HTML解析为React组件,是否可以获得alert
或类似的东西?如果可以,我该如何做?或者我做错了什么?
编辑
它不必特定是我使用的库,如果您使用过另一种类似的库并做过类似的事情,我也接受这些建议(注意,我不是在要求软件或库,而是如何在包含我的HTML的字符串中调用onClick
方法或解决方法)
编辑 2
尝试了一些方法后,我发现删除这行代码:
var reactHtml = ReactDOMServer.renderToStaticMarkup(reactElement);
删除其中一个消息。该库使用该元素测试当前HTML和解析后的HTML是否相同。对于我的情况,我不需要它,但仍然会在控制台中留下当前错误:
Warning: Invalid event handler property `onclick`. Did you mean `onClick`?
in label
in span
in div
in DireccionComponent (at App.js:47)
in App (at index.js:11)
编辑3
经过一些调查,我在这个答案中发现了dangerousSetInnerHTML
。
然后我尝试按照这个答案所述,在我的HTML中放置一个alert
,如下所示:
'<label htmlFor="float-input" onclick="alert(\'Hello\')">Hello2</label>'
而且它触发了{{alert}},但是如果我像下面的代码那样声明{{myFunction}}(注意,我尝试将其声明为一个类外部的{{function}},在类内部以及作为{{var myFunction = function(){...}}}全部和分开):
import React, {Component} from 'react';
var ReactDOMServer = require('react-dom/server');
var HtmlToReactParser = require('html-to-react').Parser;
let htmlInput = ''
//+ '<div>'
+ '<center><label className="title">Widget</label></center>'
+ '<span className="ui-float-label">'
+ '<label htmlFor="float-input" onclick="myFunction()">Hello2</label>'
+ '</span>'
//+ '</div>';
var htmlToReactParser = new HtmlToReactParser();
var reactElement = htmlToReactParser.parse(htmlInput);
class DireccionComponent extends Component {
constructor(props) {
super (props);
this.myFunction = this.myFunction.bind(this);
}
render() {
return (
<div dangerouslySetInnerHTML={{__html: htmlInput}}>
</div>
)
}
myFunction() {
console.log('Hola');
alert("Hola");
}
}
function myFunction() {
console.log('Hola');
alert("Hola");
}
export default DireccionComponent;
但是这次我遇到了一个新的错误:
ReferenceError: myFunction is not defined[Learn More]
我发现一个类似的问题:如何处理dangerouslySetInnerHTML/常规html内部的标签的onClick事件,并尝试进一步调查,找到了这个评论,其中说从
dangerouslySetInnerHTML
中获取的事件不会以这种方式触发,并提供了文档链接。因此,当我直接从onclick
方法中编写时,这似乎是一个解决方法,或者可能我没有以正确的方式执行,所以如果有更多经验的人可以尝试并澄清,那就太好了。
编辑4
我找到了一种显示 alert
的方法:
- 将HTML写成字符串
- 通过
dangerouslySetInnerHTML
设置HTML - 在React的
componentDidMount()
函数中使用纯JavaScript添加onclick
函数。 - 成功
然而,我们要做的是:
- 创建一些方法,例如:
addTwoNumbers
或类似的方法 - 从HTML字符串内部发送一个
onclick
或onClick
,调用addTwoNumbers
函数。 - 每次需要添加一个新组件时重复这个过程,该组件需要使用
addTwoNumbers
方法,只需编写HTML代码,将其保存在数据库中,然后检索它并使用它。
例如:
...
<label onClick={myFunction}> My Label </label>
...
或者正如我之前所说:
...
<label onClick={addTwoNumbers}> My Label </label>
...
让我能够获取警报的代码如下:
import React, {Component} from 'react';
import Parser from 'html-react-parser';
import {render} from 'react-dom';
var ReactDOMServer = require('react-dom/server');
var HtmlToReactParser = require('html-to-react').Parser;
let htmlInput = ''
//+ '<div>'
+ '<center><label className="title">Widget</label></center>'
+ '<span className="ui-float-label">'
+ '<label htmlFor="float-input" id="myLabel">Hello2</label>'
+ '</span>'
//+ '</div>';
var htmlToReactParser = new HtmlToReactParser();
var reactElement = htmlToReactParser.parse(htmlInput);
class DireccionComponent extends Component {
constructor(props) {
super (props);
this.myFunction = this.myFunction.bind(this);
}
render() {
return (
<div dangerouslySetInnerHTML={{__html: htmlInput}}>
</div>
)
}
componentDidMount() {
console.log('DONE');
let myLabel = document.getElementById("myLabel");
myLabel.onclick = function() {
alert();
console.log('clicked');
}
console.log(myLabel);
}
myFunction() {
console.log('Hola');
alert("Hola");
}
}
function myFunction() {
console.log('Hola');
alert("Hola");
}
export default DireccionComponent;
考虑到这一点,你知道其他实现我想做的事情的方法吗?
onclick
vsonClick
-- 你的代码中已经有后者了)。 - J. Titusonclick
和onClick
两种写法,结果都与上面的输出相同。 - FrakcoolApp.js
和package.json
吗? - Frakcool