このライブラリを使用しています: _html-to-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または回避策を含むString内でonClick
メソッドを呼び出す方法)
何かを試した後、この行を削除することがわかりました:
_var reactHtml = ReactDOMServer.renderToStaticMarkup(reactElement);
_
メッセージの1つを取り除きます。ライブラリはその要素を使用して、現在の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)
_
いくつかの調査の後、 dangerousSetInnerHTML
in this answer を見つけました。
その後、次のように この回答 HTML内にalert
を配置しようとしました。
_'<label htmlFor="float-input" onclick="alert(\'Hello\')">Hello2</label>'
_
そして、それはalert
をトリガーしましたが、下のコードのようにmyFunction
を宣言した場合(クラスの外側、クラス内、および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/regular html内の<a>タグのonClickを処理する を調べ、もう少し調べてみました このコメント which dangerouslySetInnerHTML
からのイベントはこの方法でトリガーされないことを示し、 docs にリンクします。
したがって、これはalert
メソッドから直接書き込まれたときにonclick
を取得したときの回避策のように見えましたが、おそらくより多くの経験を持つ人ができる場合は正しい方法でそれをしませんでしたそれを試して明確にし、素晴らしいだろう。
この方法でalert
を表示する方法を見つけました。
dangerouslySetInnerHTML
を介してHTMLを設定しますcomponentDidMound()
関数で、純粋なJavascriptを使用してonclick
関数を追加します。ただし、私たちがやろうとしているのはです:
addTwoNumbers
またはそのようなものonclick
関数を呼び出すHTML文字列内からonClick
またはaddTwoNumbers
を送信します。addTwoNumbers
メソッドを使用する必要がある新しいコンポーネントを追加する必要があるたびに繰り返し、そのためのHTMLを記述し、データベースに保存して取得し、それを使用するだけです。何かのようなもの:
_...
<label onClick={myFunction}> My Label </label>
...
_
または上で言ったように:
_...
<label onClick={addTwoNumbers}> My Label </label>
...
_
alert
を取得できるコードは次のとおりです。
_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;
_
これを念頭に置いて、私がやろうとしていることを行う他の方法を知っていますか?
解決策は少しハックです、コードサンドボックスにコピーアンドペースト
class App extends Component {
constructor(props) {
super(props);
this.myfunc = this.myfunc.bind(this);
}
componentDidMount() {
window.myfunc = this.myfunc;
}
myfunc() {
console.log("from myfunc");
}
componentWillUnmount() {
window.myfunc = null;
}
render() {
let inputhtml = "<a onclick=window.myfunc()>HelloWorld</a>";
return (
<div style={styles}>
<div dangerouslySetInnerHTML={{ __html: inputhtml }} />
</div>
);
}
}
特定のケースで機能するかどうかはわかりませんが、HTMLを解析することはまったく考えていません。 webpackに、さまざまなファイルのセットに対して個別のバンドルを生成するように指示できます。今、私はこれをやったことはありませんが、できることを何度か読みました。たとえば、 this です。
次に、サイトのすべての部分が変更されていないmain.bundle.jsを作成します。また、変更可能なすべてのウィジェットに対してwidget1.bundle.jsなどを作成します。それらをすべてindex.htmlにインポートします。次に、小さなバンドル(widget1など)をキャッシュしないようにWebサーバーを構成します。ユーザーがWebサイトに入るたびに、それらのウィジェットが再度ダウンロードされ、効果的に更新されます。さらに豪華にしたい場合は、各ウィジェットの現在のバージョンをAPIに提供し、そのバージョンのウィジェットバンドルに追加のフィールドを追加して、コンポーネントが最新かどうかを定期的に確認できます。ユーザーがしばらくの間ページをリロードしなかったというイベント。古くなったコンポーネントを発見した場合は、強制的にリロードするだけで、ブラウザは最新バージョンを取得します。
私はこれがあなたが行くものとは完全に異なるパスであることを知っていますが、それがあなたの特定のケースに適している場合、それは手作業でhtmlを解析し、すべてのリクエストを自分で処理します。