React.js:如何让Editor.js自定义块接入主DOM树以访问Redux
解决方案
核心问题是你在自定义块内单独调用ReactDOM.render渲染的ChecklistTool没有被包裹在顶层Redux <Provider> 的上下文范围内,所以无法访问store。以下是3种可行的实现方案:
方案1:给自定义块组件单独套Redux Provider(最简单快捷)
这个方案改动最小,直接让自定义块的组件接入全局store:
- 从你创建store的文件(通常是
store.js)中导出store实例:
// store.js 示例 import { configureStore } from '@reduxjs/toolkit' export const store = configureStore({ // 你的reducer配置 })
- 在自定义块文件中引入
store和Provider,渲染时给ChecklistTool套上Provider:
// 自定义块文件顶部新增引入 import { Provider } from 'react-redux' import { store } from '你的store文件路径' // render方法内修改ReactDOM.render部分 ReactDOM.render( <Provider store={store}> <ChecklistTool onDataChange={onDataChange} readOnly={this.readOnly} data={this.data} isAdmin={true} /> </Provider>, rootNode );
额外优化:给自定义块添加销毁方法避免内存泄漏
destroy() { ReactDOM.unmountComponentAtNode(this.nodes.holder) }
方案2:通过Editor.js配置传递需要的Redux能力(解耦性最强)
如果你不想全局导出store,也可以在初始化Editor.js的时候,把需要的Redux状态、dispatch方法通过工具配置传入自定义块:
- 初始化Editor.js时传入自定义配置:
// 你初始化Editor.js的React组件内 import { useDispatch, useSelector } from 'react-redux' const EditorComponent = () => { const dispatch = useDispatch() const userInfo = useSelector(state => state.user.info) // 你需要的状态 const editor = useMemo(() => new EditorJS({ // 其他配置 tools: { checklist: { class: Checklist, config: { reduxDispatch: dispatch, userInfo: userInfo } } } }), [dispatch, userInfo]) return <div id="editor"></div> }
- 自定义块内通过
config拿到参数,直接以props形式传给ChecklistTool:
// constructor里拿到配置 constructor({ data, config, api, readOnly }) { this.reduxDispatch = config.reduxDispatch this.userInfo = config.userInfo // 其余原有逻辑 } // render时传props ReactDOM.render( <ChecklistTool onDataChange={onDataChange} readOnly={this.readOnly} data={this.data} isAdmin={true} reduxDispatch={this.reduxDispatch} userInfo={this.userInfo} />, rootNode );
方案3:使用React Portal渲染(保持组件上下文完整)
如果你需要自定义块的组件完全属于主React树的上下文(包括除了Redux之外的其他上下文,比如路由、主题等),可以用Portal实现:
- 在你的App组件内预留一个挂载容器池,用来放自定义块的渲染节点
- 初始化Editor.js时,把创建容器节点的方法通过配置传给自定义块
- 自定义块调用方法拿到主DOM下的节点,用Portal把
ChecklistTool渲染到该节点,此时组件仍然继承主React树的所有上下文,自然可以访问Redux
内容的提问来源于stack exchange,提问作者PurplePineapple
相关产品推荐
相关产品推荐

