【React/Leaflet】没にしたL.Control用のコンポーネントの供養場
react-leafletでマップ上にUIを表示したくてL.Control
用のコンポーネントを作ったんだけども、いろいろ問題があったので没になったコンポーネントの供養。
概要
今回の記事では、react-leafletでマップ上にUIを表示したくて作ったんだけども没にしたL.Control
用のコンポーネントを紹介(供養)する。
仕様書
環境
- react 18.2.0
- react-leaflet 4.2.1
- typescript 5.2.2
手順書
コードはこんな感じ。
import React from "react";
import ReactDOM from 'react-dom/client';
import L from "leaflet";
import { useMap } from "react-leaflet";
import { ChakraProvider } from "@chakra-ui/react";
interface CustomControlProps {
position?: L.ControlPosition;
className?: string;
children: React.ReactNode;
}
const CustomControl: React.FC<CustomControlProps> = ({ children, position, className }) => {
const map = useMap();
React.useEffect(() => {
const customControl = new L.Control({ position: position });
customControl.onAdd = function () {
const div = L.DomUtil.create('div', className);
const reactRoot = ReactDOM.createRoot(div);
reactRoot.render({children});
return div;
};
customControl.addTo(map);
return () => {
customControl.remove();
};
}, [map, children, position, className]);
return null;
}
CustomControl.defaultProps = {
position: "topright",
className: ""
};
export default CustomControl;
Chakra UIを使いたい場合は下記のように{children}
を再度<ChakraProvider>
で囲む必要がある。(これをやっていいのかは怪しい気がする)
customControl.onAdd = function () {
const div = L.DomUtil.create('div', className);
const reactRoot = ReactDOM.createRoot(div);
reactRoot.render(<ChakraProvider>{children}</ChakraProvider>);
return div;
};
これでマップ上にUIを表示できるようにはなる。
没になった理由
んで、なんで没になったのかという理由をいくつか挙げる。
useEffect
時の処理が重い
例えば、Propsの値が変更されたらUIの表示の仕方を調整したい場合、再レンダーされるのでUIがちらつく程には処理が遅い。
CSSでうまくやればこの問題は回避できるとは思うんんだけども、ReactでCSSを使わない縛りプレイしてる私には問題だ。
react-redux
が使えない
これが私にとって致命的。
Chakra UIを強引に使えるようにした感じでrender
にProvider
を追加しても使えない。Provider
毎の管理になってるのでそりゃそうだ。
これもやり方次第では回避はできると思うんだけども、めんどいのでreact-redux
を使いたいんじゃ!
まとめ(感想文)
んでんで、結局どうしたのかというと
<MapContainer ...>
<Box
position="absolute"
top="16px"
left="16px"
zIndex="1000"
width="calc(100% - 32px)"
>
とんでもなく凄いUI
</Box>
</MapContainer>
こんな感じでBox
をposition="absolute"
にして配置した。
私みたいになんでもかんでもChakra UIでなんとかしたい場合に使えるかもね!