I have this code and trying to wrap a HOC with a react Class. What I want in the first place is to overwrite one part of the default params. So here is my code (you don't need to read the whole code, the question its just about the defaultProps in the HOC)
First the Component:
import React from 'react';
// recompose
import compose from 'recompose/compose';
import defaultProps from 'recompose/defaultProps';
import withState from 'recompose/withState';
import withHandlers from 'recompose/withHandlers';
import withProps from 'recompose/withProps';
// utils
import { themr } from 'react-css-themr';
import { suslovkaCoords, generateMarkers } from './utils/fakeData';
// controls
import CanvasHoverMap from './controls/Map';
import HoveredTooltipMarker from './controls/Markers/HoveredTooltipMarker';
import TooltipMarker from './controls/Markers/TooltipMarker';
// components
import RoomTooltip from '../RoomTooltip/RoomTooltip';
// styles
import styles from './map.sass';
import mapStyles from './controls/Map/mapSytles';
const MARKERS_COUNT = 3000;
export const map = ({
theme,
style,
options,
markerHoverDistance,
markers,
renderMarkers,
renderMarker,
mapParams: {
zoom,
center,
},
setMapParams,
onMapParamsChange,
selectedMarker,
setSelectedMarker,
isMobile,
refresh,
}) => (
<div className={theme.component}>
<CanvasHoverMap
// flex: 1 here
style={style}
// google map options https://developers.google.com/maps/documentation/javascript/controls#ControlOptions
options={options}
// see CanvasMap onMouseMove, distance at which algorithm decides that marker is hovered
markerHoverDistance={markerHoverDistance}
// google-map-react props
center={center}
zoom={zoom}
onChange={onMapParamsChange}
// canvas markers, and render functions
markers={markers}
// render markers at canvas
renderMarkers={renderMarkers}
// render hovered marker as is
renderMarker={renderMarker}
// to force redraw just pass a new empty object to refresh for example
refresh={refresh}
// selected marker always visible over canvas (+ tooltip)
selectedMarker={selectedMarker}
setSelectedMarker={setSelectedMarker}
// mobile-detect
isMobile={isMobile}
setMapParams={setMapParams}
/>
</div>
);
Now the HOC:
export const mapHOC = compose(
themr('map', styles),
defaultProps({
options: {
scrollwheel: true,
zoomControl: true,
zoomControlOptions: {
position: 1, // google.maps.ControlPosition.LEFT_TOP
},
minZoom: 3,
zoom: 10,
maxZoom: 18,
// disableDoubleClickZoom: true,
styles: mapStyles,
},
style: {
flex: 1,
},
hoverDistance: 15,
markerHoverDistance: 15,
markers: generateMarkers(MARKERS_COUNT, 0.0003),
}),
withState('mapParams', 'setMapParams', { center: suslovkaCoords, zoom: 8 }),
withState('selectedMarker', 'setSelectedMarker', null),
withProps(({ selectedMarker }) => ({
isSelected: (marker) => selectedMarker
? selectedMarker.id === marker.id
: false,
})),
withHandlers({
onMapParamsChange: ({ setMapParams }) => ({ center, zoom, bounds }) => {
setMapParams({ center, zoom, bounds });
console.log('setMapParams', { center, zoom });
},
renderMarker: ({ theme, setSelectedMarker, isSelected, isMobile }) => (marker) => {
const tooltipMarkerProps = {
key: marker.id,
theme: {theme},
themeNamespace: 'tooltipMarker',
initialScale: 1,
defaultScale: 1,
hoveredScale: 1.3,
tooltipContent: <RoomTooltip marker={marker} />,
paddingOffset: 10, // used for tooltip position
tooltipContentHeight: 240, // no need to be exact, used for tooltip position
tooltipContentWidth: 200, // no need to be exact, used for tooltip position
setSelectedMarker: setSelectedMarker,
selected: isSelected(marker),
marker: marker,
...marker,
};
return isMobile
? <TooltipMarker {...tooltipMarkerProps } />
: <HoveredTooltipMarker {...tooltipMarkerProps} />;
},
// be sure in current implementation markers is tile markers, not all markers.
// tiling is used as it allows some perf optimizations not used here
renderMarkers: () => ({ ctx, markers, tileSize }) => {
ctx.clearRect(0, 0, tileSize, tileSize);
const radius = 5;
markers.forEach(({ /* id, */ x, y }) => {
// just circles here but can be images, use id or other marker props to render
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.beginPath();
ctx.arc(x, y, radius + 3, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
ctx.fillStyle = 'white';
ctx.beginPath();
ctx.arc(x, y, radius + 2, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
ctx.fillStyle = '#00b92a';
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
});
},
}),
);
I would like to remove "markers: generateMarkers(MARKERS_COUNT, 0.0003)" from defaultProps and give the markers from the outside.
What I tried so far:
const newmap = mapHOC(map);
class MapWithState extends React.Component {
constructor(props) {
super(props);
}
render() {
const markers = generateMarkers(MARKERS_COUNT, 0.0003);
return (<newmap markers={markers} />);
}
}
export default MapWithState;
//export default mapHOC(map);
Any idea how to do something like this? I hope that it can be done without much trouble. Thanks!
React merge Props when a component is being created.
Mean, when a component(JSX) is being instantiated it creates a public data and private data to it i.e, state and props respectively.
When creating props to a component it takes all the argument props (from callee) and also considers if any default props are declared in that class which it can fill in.
Something like Object.assign({}, { ...defaultProps }, { ...userProps })
where defaultProps
will be overrided with userProps
. If userProps
are not availble then defaultProps
would be considered.
So, in your case you need to delete a default prop, <newmap markers={markers} />
this should work.