从dangouslysetinnerhtml中的onclick调用React组件函数
Call React Component Function from onclick in dangerouslySetInnerHTML
React新手。我有一个contenteditable
div,它有dangerouslySetInnerHTML
作为子div,因为我需要在运行时格式化用户输入的任何内容。在一个特定的span内点击HTML,我想setState
的一个变量的包含组件。
这能做到吗?
如果不是,我应该如何改变我的结构?
代码如下:
updateText:function(){
var txt = $('#text_Box').text();
if(txt.indexOf('@Name') > -1)
{
txt = txt.replace('@Name','<span class=''tagged'' contenteditable = ''false'' onclick=''doSomething()''>:Name</span>');
}
this.setState({userText:txt});
},
render:function(){
return <div className="inputDiv" contentEditable="true" type="text" className="form-control" id="text_Box" dangerouslySetInnerHTML={{__html:this.state.userText}} onInput = {this.updateText} />
}
我要讲的是doSomething()方法
如果你想让你的span响应点击事件,你应该只在你的组件被重新渲染后才分配事件处理程序(doSomething),因为当你向innerHtml传递新值时,该组件中的所有事件处理程序都会被清理。另一个解决方案是像这样使用事件委托:
onClick: function(e) {
var $el = $(e.target);
if ($el.is('span.tagged')) {
this.doSomething($el);
}
},
render:function(){
return (
<div
className="inputDiv form-control"
contentEditable="true"
onClick={this.onClick}
type="text"
id="text_Box"
dangerouslySetInnerHTML={{__html: this.state.userText}}
onInput={this.updateText} />
);
}
另一个可能的解决方案是使用createElement, createTextNode和appendChild方法直接使用DOM树
试试这个:
updateText: function() {
var txt = $('#text_Box').text();
if (txt.indexOf('@Name') > -1) {
txt = txt.replace('@Name', '<span class="tagged" contenteditable="false" onclick="' + this.doSomething() + '">:Name</span>');
}
this.setState({userText: txt});
},
render:function(){
return (
<div
className="inputDiv form-control"
contentEditable="true"
type="text"
id="text_Box"
dangerouslySetInnerHTML={{__html: this.state.userText}}
onInput={this.updateText} />
);
}
我最近有一个类似的需求。react应用程序被赋予了一个带有href属性的html块,需要将其转换为onClick事件,以便我们可以在react应用程序中解析和路由链接。
我的解决方案是使用正则表达式,然后注册我自己的事件监听器
//given a block of html as a string
myHtml = '<div href="/goSomewhere"></div>'
//match all href attributes
let reg: RegExp = /href=".*?"/g
//replace the href attribute with a custom "resolve" attribute
myHtml.replace(reg, (href: string) => {
//then match any characters between the quotation marks in the href attribute to extract the uri itself
let uri = href.match(/(?<=href=").*?(?=")/g)
return `resolve="${uri}"`
})
//Render the html
render() {
return <div dangerouslySetInnerHTML = {{__html: myHtml}} />
}
//helper function to return an array containing all nodes with a "resolve" attribute
getElementByAttribute(attr: string) {
let nodeList = document.getElementsByTagName('*')
let nodeArray = []
for (let i = 0; i < nodeList.length; i++) {
if (nodeList[i].getAttribute(attr)) nodeArray.push(nodeList[i])
}
return nodeArray
}
//once rendered find the tag that require resolving
componentDidUpdate() {
let nodes = this.getElementByAttribute('resolve')
for (let i = 0; i < nodes.length; i++) {
//create pointer outside of the onclick event allowing closure
let href = nodes[i].getAttribute('resolve')
nodes[i].addEventListener('click', (e) => {
if (href) this.linkResolver(href);
})
//remove the custom attribute to cleanup
nodes[i].removeAttribute('resolve')
}
}
//linkResolver is a function within react
//you now have an onclick event triggered from dangerouslySetInnerHTML
linkResolver(href: string) {
console.log(href)
}
相关文章:
- React组件等待所需道具进行渲染
- React组件-设置页面标题
- 为react组件传递道具的最佳方式
- react组件中的绑定方法
- 加载服务器端渲染的React组件后执行脚本
- 如何基于依赖性导入React组件
- 可以't在我的React组件中加载图像
- jsx-React组件中的格式化编号
- 在进行服务器端渲染时,我可以向客户端发送React组件吗
- 使用jquery在react组件内部设置样式可以吗
- 为什么我不能将键映射到 React 组件上
- webpack样式加载器-在react组件上导入不同的样式,而无需重写
- 无法将react组件作为属性传递给另一个组件
- 继承React组件的正确方式
- 在JSX中围绕React组件封装高阶组件(HOC)
- 根据React组件的名称渲染该组件
- react组件的正确命名规范
- 在另一个文件夹中显示React组件
- AJAX 请求没有在我的 React 组件中设置 this.state.data
- 有没有一条清晰的路径,我可以实现一个在 ScalaJS + React 中广泛使用上下文的 React 组件