https://github.com/exuanbo/codemirror-toolkit/tree/main/packages/react
一个小巧灵活的在 React 中使用 CodeMirror 6 的解决方案,打包体积只有 ~1.5kB minified + gizipped 。
import { createCodeMirror } from '@codemirror-toolkit/react'
const codeMirror = createCodeMirror<HTMLDivElement>((prevState) => ({
doc: prevState?.doc ?? 'Hello World!',
// ...otherConfig,
}))
// if you want to use them in other files
export const { useViewEffect, useContainerRef, /* ... */ } = codeMirror
function Editor() {
useViewEffect((view) => {
console.log('EditorView is created')
return () => {
console.log('EditorView will be destroyed')
}
}, [])
const containerRef = useContainerRef()
return <div ref={containerRef} />
}
function App() {
const [showEditor, setShowEditor] = useState(true)
return (
<>
<button onClick={() => setShowEditor(!showEditor)}>
{showEditor ? 'Destroy' : 'Create'} Editor
</button>
{showEditor && <Editor />}
</>
)
}
可以看出 API 的设计借鉴了 zustand 很多,也可以搭配 Context Provider 来使用:
const {
Provider: CodeMirrorProvider,
useView,
useContainerRef,
// ...
} = createCodeMirrorWithContext<HTMLDivElement>('CodeMirrorContext')
function MenuBar() {
const view = useView()
// ...
}
function Editor() {
const containerRef = useContainerRef()
return <div ref={containerRef} />
}
function App({ initialInput }: { initialInput: string }) {
return (
<CodeMirrorProvider
config={{
doc: initialInput,
// ...otherConfig,
}}>
<MenuBar />
<Editor />
</CodeMirrorProvider>
)
}
Source | Playground |
---|---|
react-with-context | Open in StackBlitz |
react-with-extension-manager | Open in StackBlitz |
react-with-view-update-listener | Open in StackBlitz |