2017-10-22 3 views
0

Ich habe diesen Code und versuche, eine HOC mit einer Reaktionsklasse zu wickeln. Was ich in erster Linie will, ist einen Teil der Standardparameter zu überschreiben. So, hier ist mein Code (Sie nicht den ganzen Code lesen müssen, die Frage seiner nur über die defaultProps im HOC)Higher Order Component: Standard Requisiten

Zuerst wird die Komponente:

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> 
); 

Nun ist die 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(); 
     }); 
    }, 
    }), 
); 

ich möchte „Marker: generateMarkers (MARKERS_COUNT, 0,0003) entfernen“ aus defaultProps und die Markierungen von außen geben.

Was habe ich versucht, so weit:

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); 

Jede Idee, wie so etwas zu tun? Ich hoffe, dass es ohne viel Mühe gemacht werden kann. Vielen Dank!

Antwort

0

Reagiere Merge Requisiten, wenn eine Komponente erstellt wird.

Wenn eine Komponente (JSX) instanziiert wird, erstellt sie öffentliche Daten und private Daten, d. H. State und Props.

Wenn Requisiten zu einer Komponente zu schaffen nimmt es alle Argument Requisiten (von Angerufenen) und berücksichtigt auch, ob irgendwelche Standard Requisiten in dieser Klasse deklariert sind, die sie ausfüllen können.

So etwas wie Object.assign ({} , {... defaultProps}, {... userProps}) , wo Standardrequisiten mit Benutzerrequisiten überschrieben werden. Wenn Nutzerrequisiten nicht verfügbar sind, werden Standardrequisiten berücksichtigt.

Also, in Ihrem Fall müssen Sie eine Standard-Prop, <newmap markers={markers} /> löschen dies sollte funktionieren.

+0

Vielen Dank. Das habe ich versucht. Es hat nicht zuerst funktioniert, aber nach einem zweiten Versuch hat alles gut funktioniert. Es war sogar nicht notwendig, die Standardrequisiten zu löschen! – MichaelRazum

Verwandte Themen