如何从内部HTML回调到React组件状态?



我知道这不是一个好问题,但我没有其他选择。我使用的是来自React包装器的Frappe甘特图库(https://www.npmjs.com/package/react-frappe-gantt)

我修改了react- trap -gantt以通过custom_popup_html以允许自定义表单。目标是允许用户"添加里程碑"。从工具栏,然后从甘特图的里程碑用户点击它,看到一个弹出的一些详细信息和"添加动作";按钮,它将回调到我的React组件状态,以显示完整的"添加动作"。模态。

问题是,frappgantt只接受一个HTML字符串作为custom_popup_html的值。按钮应该在字符串里面

下面是一个例子:

handleActionPopup(task) {
return `
<div class='details-container'>
<h5>${task.name}</h5>
<button onclick="console.log('Add action')">Add Action</button>
</div>
`
}
...
render() {
...
<Gantt
tasks={tasks}
customPopupHtml={(task) => this.handleActionPopup(task) }
/>
}

控制台当然会显示点击动作,但我需要以某种方式将其回调到组件中。

我不能附加ref,因为我可以告诉因为这不是JSX渲染对象,它必须是一个HTML字符串。

我可以使用JS设置或触发我的React组件侦听的一些DOM事件。它不是很好,但使用冰沙比避免黑客攻击更有价值。

我如何连接/监听/回调/调用React组件从按钮的点击事件?谢谢!

K我想出了一个方法来处理这个问题,通过在componentDidMount()中将Component函数分配给窗口,并从内部HTML中调用它,然后在componentWillUnmount()中将其从窗口中删除。不是很好,但是很干净

import { render } from 'react-dom'
import { Component } from 'react'
class App extends Component {
state = {
test: 'uninitialized'
}
tasks = [
{
id: 'Task 1',
name: 'Redesign website',
start: '2016-12-28',
end: '2016-12-31',
progress: 10,
dependencies: ''
},
{
id: 'Task 2',
name: 'Redesign website 2',
start: '2016-12-28',
end: '2016-12-31',
progress: 20,
dependencies: 'Task 1'
}
]
testFunc = txt => {
this.setState({ test: txt })
}
componentDidMount() {
window.testFunc = this.testFunc
}
componentWillUnmount() {
delete window.testFunc
}
handleActionPopup(task) {
return `
<div class='details-container'>
<h5>${task.name}</h5>
<button onclick="window.testFunc('${task.name}')">Add Action</button>
</div>
`
}
render() {
return (
<div>
<div>{this.state.test}</div>
<Gantt
tasks={this.tasks}
customPopupHtml={task => this.handleActionPopup(task)}
/>
</div>
)
}
}
function Gantt(props) {
return (
<div>
{props.tasks.map(task => (
<button
key={task.name}
onClick={() => {
const popupHtml = props.customPopupHtml(task)
const wrapperForPopup = document.querySelector('#wrapperForPopup')
wrapperForPopup.innerHTML = popupHtml
}}
>
{task.name}
</button>
))}
<div id="wrapperForPopup" style={{ marginTop: 30 }} />
</div>
)
}
render(<App />, document.getElementById('root'))

如果有人有其他选择,我洗耳恭听。

最新更新