TinyMCE自定义工具栏按钮无法获取更新后的React状态值
问题:React中TinyMCE自定义工具栏按钮无法获取更新后的state值
在React项目中使用TinyMCE编辑器时,自定义工具栏按钮的点击事件始终只能获取到state的初始值,无法访问更新后的值。
示例代码
function App() { const [state, setState] = React.useState(0); const handleAction = (editor) => { console.log("State", state); // 始终获取初始状态 }; return ( <> <button onClick={() => setState(state + 1)}>Add me</button> <p>State: {state}</p> <Editor apiKey="XXX" init={{ toolbar: "myCustomToolbarButton", setup: (editor) => { editor.ui.registry.addButton("myCustomToolbarButton", { text: "My Custom Button", onAction: (editor) => { handleAction(editor); } }); } }} /> </> ); }
复现步骤
- 点击「My Custom Button」按钮,查看控制台输出。
- 点击「Add me」按钮更新state值。
- 再次点击「My Custom Button」,发现仍获取初始状态值。
解决方案
方法一:使用useRef保存最新state值(推荐)
问题根源在于TinyMCE的setup函数仅在编辑器初始化时执行一次,onAction回调会捕获初始的state闭包,后续state更新后无法同步。通过useRef可以保存最新的state值,因为ref的current属性是可变的,不受闭包限制。
function App() { const [state, setState] = React.useState(0); const stateRef = React.useRef(state); // 每次state更新时同步ref的current值 React.useEffect(() => { stateRef.current = state; }, [state]); const handleAction = (editor) => { console.log("State", stateRef.current); // 现在能获取最新状态 }; return ( <> <button onClick={() => setState(state + 1)}>Add me</button> <p>State: {state}</p> <Editor apiKey="XXX" init={{ toolbar: "myCustomToolbarButton", setup: (editor) => { editor.ui.registry.addButton("myCustomToolbarButton", { text: "My Custom Button", onAction: (editor) => { handleAction(editor); } }); } }} /> </> ); }
方法二:通过key触发编辑器重新初始化(不推荐)
给Editor组件添加key属性,当state变化时更新key,触发编辑器重新渲染,此时setup函数会重新执行,onAction回调会捕获最新的state。但这种方法会重置编辑器的内容和状态,仅适用于不需要保留编辑器内容的场景。
function App() { const [state, setState] = React.useState(0); const handleAction = React.useCallback((editor) => { console.log("State", state); }, [state]); return ( <> <button onClick={() => setState(state + 1)}>Add me</button> <p>State: {state}</p> <Editor key={state} apiKey="XXX" init={{ toolbar: "myCustomToolbarButton", setup: (editor) => { editor.ui.registry.addButton("myCustomToolbarButton", { text: "My Custom Button", onAction: (editor) => { handleAction(editor); } }); } }} /> </> ); }
内容的提问来源于stack exchange,提问作者Shivam Verma
相关产品推荐
相关产品推荐

