在 react-contenteditable 中渲染 JSX 元素
Render JSX element in react-contenteditable
在react-contenteditable
中,html
属性只接受string
,我如何设法在字符串中添加带有eventlistener
的JSX元素。
import ContentEditable from "react-contenteditable";
import "./styles.css";
const text = "I want to order cheese chicken pizza.";
const Elems = {
cheese: (
<span style={{ color: "red" }} onClick={() => alert("clicked cheese span")}>
cheese
</span>
),
chicken: (
<span
style={{ color: "red" }}
onClick={() => alert("clicked chicken span")}
>
chicken
</span>
)
};
export default function App() {
const swapText = () => {
const text_array = text.split(" ");
console.log(text_array);
const a = text_array.map((item) => {
if (item in Elems) item = Elems[item];
else item += " ";
return item;
});
return a;
};
return (
<div className="App">
<h2>React contenteditable</h2>
<ContentEditable html={swapText()} />
</div>
);
}
您可以使用 ReactDOMServer.renderToStaticMarkup(element)
将 React 元素转换为标记。这对样式有帮助,但对点击处理程序没有帮助:
if (item in Elems) item = renderToStaticMarkup(Elems[item]);
要使项目可点击,您需要将 onClick
处理程序传递给 <ContentEditable>
组件(或其父组件):
<ContentEditable onClick={handleClick} html={swapText()} />
您还需要确定可点击的元素。在这个例子中,我为它们都添加了 data-action
标签:
const Elems = {
cheese: (
<span style={{ color: 'red' }} data-action="cheese">
cheese
</span>
),
chicken: (
<span style={{ color: 'red' }} data-action="chicken">
chicken
</span>
)
};
点击处理程序使用 Element.closest()
搜索事件目标或具有 data-action
标签的父级,如果它找到一个,它将作用于标签值:
const handleClick = (e) => {
const target = e.target.closest('[data-action]');
if (!target) return;
const action = target.dataset.action;
alert(action);
};
工作示例 - sandbox
在react-contenteditable
中,html
属性只接受string
,我如何设法在字符串中添加带有eventlistener
的JSX元素。
import ContentEditable from "react-contenteditable";
import "./styles.css";
const text = "I want to order cheese chicken pizza.";
const Elems = {
cheese: (
<span style={{ color: "red" }} onClick={() => alert("clicked cheese span")}>
cheese
</span>
),
chicken: (
<span
style={{ color: "red" }}
onClick={() => alert("clicked chicken span")}
>
chicken
</span>
)
};
export default function App() {
const swapText = () => {
const text_array = text.split(" ");
console.log(text_array);
const a = text_array.map((item) => {
if (item in Elems) item = Elems[item];
else item += " ";
return item;
});
return a;
};
return (
<div className="App">
<h2>React contenteditable</h2>
<ContentEditable html={swapText()} />
</div>
);
}
您可以使用 ReactDOMServer.renderToStaticMarkup(element)
将 React 元素转换为标记。这对样式有帮助,但对点击处理程序没有帮助:
if (item in Elems) item = renderToStaticMarkup(Elems[item]);
要使项目可点击,您需要将 onClick
处理程序传递给 <ContentEditable>
组件(或其父组件):
<ContentEditable onClick={handleClick} html={swapText()} />
您还需要确定可点击的元素。在这个例子中,我为它们都添加了 data-action
标签:
const Elems = {
cheese: (
<span style={{ color: 'red' }} data-action="cheese">
cheese
</span>
),
chicken: (
<span style={{ color: 'red' }} data-action="chicken">
chicken
</span>
)
};
点击处理程序使用 Element.closest()
搜索事件目标或具有 data-action
标签的父级,如果它找到一个,它将作用于标签值:
const handleClick = (e) => {
const target = e.target.closest('[data-action]');
if (!target) return;
const action = target.dataset.action;
alert(action);
};
工作示例 - sandbox