Skip to content

Commit

Permalink
feat(marker): 解决渲染报错
Browse files Browse the repository at this point in the history
  • Loading branch information
wangxingkang committed Jan 16, 2024
1 parent d9c3c59 commit f490ca6
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 68 deletions.
66 changes: 66 additions & 0 deletions src/hooks/usePropsReactive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { isEqual } from 'lodash-es';
import { isFunction } from '@pansy/shared';
import { useDeepCompareEffect, useUnmount, usePrevious } from '@pansy/react-hooks';
import { toCapitalString } from '@/utils';

interface Options {
setterMap?: Record<string, Function>;
converterMap?: Record<string, Function>;
}

export function usePropsReactive<
Ins extends Record<string, any> = any,
P extends Record<string, any> = {},
>(props: P, ins: Ins, { setterMap = {}, converterMap = {} }: Options = {}) {
const prevProps = usePrevious(props) as P;

const onInstanceCreated = (instance: Ins) => {
reactivePropChange(props, false);
};

/**
* 对参数变化进行处理
* @param nextProps
* @param shouldDetectChange
* @returns
*/
const reactivePropChange = (nextProps: P, shouldDetectChange: boolean = true) => {
if (!ins) return;

try {
Object.keys(nextProps).forEach((key) => {
/** 忽略事件绑定处理 */
if (isFunction(props[key]) && /^on[A-Z]/.test(key)) return;

let willReactive = true;
if (shouldDetectChange) {
willReactive = !isEqual(nextProps[key], prevProps?.[key]);
}
if (!willReactive) return;

let setterParam = nextProps[key];
// 对值进行转换
if (key in converterMap) {
setterParam = converterMap[key](nextProps[key]);
}

// 设置值
if (key in setterMap) {
setterMap[key](setterParam, ins);
} else {
const trySetterName = `set${toCapitalString(key)}`;

if (trySetterName in ins) {
ins[trySetterName](setterParam);
}
}
});
} catch (error) {
console.error(error);
}
};

return {
onInstanceCreated,
};
}
18 changes: 6 additions & 12 deletions src/marker/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { toLngLat } from '../utils/toLngLat';

import type { LngLatLike, Marker } from 'mapbox-gl';
import type { EventMapping, PropKey } from './types';
import type { EventMapping, PropKeys } from './types';

export const mapEventMap: EventMapping = {
onDragStart: 'dragstart',
Expand All @@ -10,10 +9,10 @@ export const mapEventMap: EventMapping = {
};

/** 静态属性 */
export const StaticProps: PropKey[] = ['anchor', 'clickTolerance', 'color', 'onClick'];
export const StaticProps: PropKeys[] = ['anchor', 'clickTolerance', 'color', 'onClick'];

/** 动态属性 */
export const NativeDynamicProps: PropKey[] = [
export const NativeDynamicProps: PropKeys[] = [
'draggable',
'offset',
'rotation',
Expand All @@ -25,13 +24,8 @@ export const NativeDynamicProps: PropKey[] = [

export const allProps = NativeDynamicProps.concat(StaticProps);

export const setterMap = {
lnglat(value: LngLatLike, marker: Marker) {
if (!marker) return;
const lnglat = toLngLat(value);
export const setterMap = {};

lnglat && marker.setLngLat(lnglat);
},
export const converterMap: Partial<Record<PropKeys, (...value: any[]) => any>> = {
lnglat: toLngLat,
};

export const converterMap = {};
50 changes: 0 additions & 50 deletions src/marker/index.md

This file was deleted.

39 changes: 34 additions & 5 deletions src/marker/marker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@ import { useReact } from '@/hooks/useReact';
import { allProps, setterMap, converterMap } from './config';

import type { Marker as MapboxMarker, MarkerOptions } from 'mapbox-gl';
import type { MarkerProps, EventMapping } from './types';
import type { MarkerProps, EventMapping, PropKeys } from './types';

export const Marker = forwardRef<MapboxMarker, MarkerProps>((props, ref) => {
const { map } = useMap();
const { Portal, container } = usePortal();
const [marker, setMarker, getMarker] = useGetState<MapboxMarker | undefined>(undefined);

// const { onInstanceCreated } = usePropsReactive(
// props,
// marker!,
// {
// setterMap,
// converterMap
// }
// );

const { onInstanceCreated } = useReact<MarkerProps, MapboxMarker, EventMapping>(props, {
ins: marker,
setterMap,
Expand Down Expand Up @@ -45,24 +54,44 @@ export const Marker = forwardRef<MapboxMarker, MarkerProps>((props, ref) => {

const createInstance = () => {
const options = getCreateOptions(props);
const marker = new Mapbox.Marker(container, options);

return Promise.resolve(marker);
if (options.lnglat) {
const marker = new Mapbox.Marker(container, options);
marker.setLngLat(options.lnglat);

return Promise.resolve(marker);
} else {
return Promise.reject();
}
};

/** 获取创建参数 */
const getCreateOptions = (props: MarkerProps) => {
const options: MarkerOptions = {};
const options: MarkerOptions & {
lnglat?: MarkerProps['lnglat'];
} = {};

allProps.forEach((key) => {
if (key in props) {
// @ts-ignore
options[key] = props[key];
options[key] = getSetterValue(key, props);
}
});

return options;
};

const getSetterValue = (key: PropKeys, props: MarkerProps) => {
let value = props[key];

if (key in converterMap) {
try {
value = converterMap[key]?.(props[key]);
} catch (error) {}
}

return value;
};

return <>{marker && <Portal>{props.children}</Portal>}</>;
});
2 changes: 1 addition & 1 deletion src/marker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ export interface MarkerProps
children?: React.ReactNode;
}

export type PropKey = KeysOfUnion<MarkerProps>;
export type PropKeys = KeysOfUnion<MarkerProps>;

0 comments on commit f490ca6

Please sign in to comment.