2017-10-22 2 views
0

이 코드를 가지고 있으며 HOC를 react 클래스로 래핑하려고합니다. 내가 제일 먼저 원하는 것은 기본 매개 변수의 일부를 덮어 쓰는 것입니다. 그래서 여기 내 코드 (는 전체 코드에게 질문을 읽을 필요가 없습니다 그 단지 HOC에서 defaultProps에 대한)Higher Order 구성 요소 : 기본 눅눅한

첫 번째 구성 요소 :

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

이제 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(); 
     }); 
    }, 
    }), 
); 

defaultProps에서 "marker : generateMarkers (MARKERS_COUNT, 0.0003)"를 제거하고 바깥 쪽에서 마커를 제공하고 싶습니다.

는 지금까지 시도하는 것 :

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

어떤 생각이 어떻게 이런 일을 할 수 있나요? 많은 어려움없이 그 일이 이루어지기를 바랍니다. 감사!

답변

0

구성 요소를 생성 할 때 반응하는 병합 소품.

평균적으로 구성 요소 (JSX)가 인스턴스화 될 때 공용 데이터와 개인 데이터, 즉 상태와 소품을 각각 만듭니다.

구성 요소에 소품을 만드는이 (수신자에서) 모든 인수 소품을 소요하고 또한 어떤 기본 소품은 채울 수 클래스에 선언하는 경우 고려합니다.

Object.assign 같은 뭔가 ({} , {... defaultProps}, {... userProps}) 여기서 기본 소품은 사용자 소품으로 대체됩니다. 사용자 소품이 제공되지 않으면 기본 소품이 고려됩니다.

귀하의 경우 기본 소품을 삭제해야합니다. <newmap markers={markers} /> 이것이 효과가 있습니다.

+0

고맙습니다. 그게 내가하려는 일이다. 처음에는 효과가 없었지만 두 번째 시도 후에는 모든 것이 잘 작동했습니다. 기본 소품을 삭제할 필요가 없었습니다! – MichaelRazum

관련 문제