2017-08-18 62 views
-8

我正在研究一個演示反應應用程序 - 它的重要性在於將redux添加到此應用程序中。請檢查以下代碼,並幫助我適當調用redux。如何重做Reactjs犯罪地圖應用程序

我想了解如何在稍後將姐妹組件添加到此類應用程序以共享此通信通道 - 如果它是在圖表/組件之間創建主/從關係的話。

// index.js

import React, { Component } from 'react' 
import { render } from 'react-dom' 
//import { Provider } from 'react-redux' 
//import { createStore } from 'redux' 

import MapChart from './modules/mapChart/MapChart' 
import './index.css' 

// this is how you'll get your icon links 
// instead of a switch with loads of repetitive bytes 
const iconMap = { 
    'anti-social-behaviour': 'green-dot', 
    'burglary':    'red-dot', 
    'criminal-damage-arson': 'yellow-dot', 
    'drugs':     'purple-dot', 
    'other-theft':   'pink-dot', 
    'shoplifting':   'blue-dot', 
    'vehicle-crime':   'orange-dot', 
    'other-crime':   'ltblue-dot' 
} 

// this is a class because it needs state 
class CrimeMap extends Component { 
    // to do this you have to make sure you have 
    // the transform-class-properties feature in babel 
    // otherwise just set your initial state in a constructor 
    // constructor(props) { 
    // super(props) 
    // this.state = { markers: [] } 
    // } 
    state = { 
    markers: [] 
    } 

    componentDidMount() { 
    // use fetch instead of jQuery 
    // jQuery is a big lib to be loading for some fetching 
    fetch(this.props.source) 
     .then(response => response.json()) 
     .then(
     json => this.setState({ 
      markers: this.mapLayerData(json) 
     }), 
     err => { 
      // handle errors 
     } 
    ) 
    } 

    // store only the data you want to pass as props to each Marker 
    // instead of mapping it directly in MapChart every time it renders 
    mapLayerData(markers) { 
    // use a standard map function instead of $.each 
    // destructuring saves time and repetition 
    return markers.map(({ category, location }) => ({ 
     // use a template string and a simple map of icon names to get your icon uri 
     icon: 'http://maps.google.com/mapfiles/ms/icons/'+ iconMap[category] +'.png', 
     label: category, 
     name: category, 
     position: { 
     lat: location.latitude, 
     lng: location.longitude 
     } 
    })) 
    } 

    render() { 
    // there's only one layer, so render it directly 
    return (
     <div className="app"> 
     <MapChart markers={this.state.markers} /> 
     </div> 
    ) 
    } 
} 

//https://data.police.uk/docs/method/crime-street/ 
render(
    <CrimeMap source="https://data.police.uk/api/crimes-street/all-crime?poly=52.268,0.543:52.794,0.238:52.130,0.478&date=2017-01" />, 
    document.getElementById('root') 
); 

// MapChart.js

import React from 'react' 
// only load what you're actually using 
import { Map, Marker, GoogleApiWrapper } from 'google-maps-react' 
import './MapChart.css' 

// this is a stateless component, it doesn't need state or event handlers 
const MapContainer = ({ google, markers }) => (
    <Map 
    google={google} 
    initialCenter={{ 
     lat: 52.268, 
     lng: 0.543 
    }} 
    zoom={9} 
    > 
    { 
     markers.map((marker, i) => 
     // since you've mapped your data to just the props you need 
     // you can just spread it into the component 

     <Marker 
      key={i} 
      icon={marker.icon} 
      title={marker.label} 
      name={marker.name} 
      position={{lat: marker.position.lat, lng: marker.position.lng}} /> 

    ) 
    } 
    </Map> 
) 

export default GoogleApiWrapper({ 
    apiKey: 'xxxxx' 
})(MapContainer) 

// MapChart.css

/* Always set the map height explicitly to define the size of the div 
    * element that contains the map. */ 
    #map { 
    height: 100%; 
    } 
    /* Optional: Makes the sample page fill the window. */ 
    html, body { 
    height: 100%; 
    margin: 0; 
    padding: 0; 
    } 

////////// ///

這就像我已經加入了redux - 但我收到錯誤

操作必須是普通對象。使用自定義中間件進行異步操作。我基於這個例子 - 但我不明白如何添加/定義這個thunk?這是什麼?

http://jsfiddle.net/cdagli/b2uq8704/6/

index.js

import React, { Component } from 'react' 
import { render } from 'react-dom' 
import {Provider, connect} from 'react-redux' 
import {createStore, applyMiddleware} from 'redux' 
import thunk from 'redux-thunk'; 

import MapChart from './modules/mapChart/MapChart' 
import './index.css' 

function fetchPostsRequest(){ 
    return { 
    type: "FETCH_REQUEST" 
    } 
} 

function fetchPostsSuccess(payload) { 
    return { 
    type: "FETCH_SUCCESS", 
    payload 
    } 
} 

function fetchPostsError() { 
    return { 
    type: "FETCH_ERROR" 
    } 
} 

const reducer = (state = {}, action) => { 
    switch (action.type) { 
    case "FETCH_REQUEST": 
     return state; 
    case "FETCH_SUCCESS": 
     return {...state, posts: action.payload}; 
    default: 
     return state; 
    } 
} 

function fetchPostsWithRedux() { 
    return (dispatch) => { 
    dispatch(fetchPostsRequest()); 
    return fetchPosts().then(([response, json]) =>{ 
     if(response.status === 200){ 
     dispatch(fetchPostsSuccess(json)) 
     } 
     else{ 
     dispatch(fetchPostsError()) 
     } 
    }) 
    } 
} 

function fetchPosts() { 
    const URL = 'https://data.police.uk/api/crimes-street/all-crime?poly=52.268,0.543:52.794,0.238:52.130,0.478&date=2017-01'; 
    return fetch(URL, { method: 'GET'}) 
    .then(response => Promise.all([response, response.json()])); 
} 



// this is how you'll get your icon links 
// instead of a switch with loads of repetitive bytes 
const iconMap = { 
    'anti-social-behaviour': 'green-dot', 
    'burglary':    'red-dot', 
    'criminal-damage-arson': 'yellow-dot', 
    'drugs':     'purple-dot', 
    'other-theft':   'pink-dot', 
    'shoplifting':   'blue-dot', 
    'vehicle-crime':   'orange-dot', 
    'other-crime':   'ltblue-dot' 
} 

// this is a class because it needs state 
class CrimeMap extends Component { 
    // to do this you have to make sure you have 
    // the transform-class-properties feature in babel 
    // otherwise just set your initial state in a constructor 
    // constructor(props) { 
    // super(props) 
    // this.state = { markers: [] } 
    // } 
    state = { 
    markers: [] 
    } 

    componentDidMount() { 
    console.log('prop ', this.props) 
    // use fetch instead of jQuery 
    // jQuery is a big lib to be loading for some fetching 
    fetch(this.props.source) 
     .then(response => response.json()) 
     .then(
     json => this.setState({ 
      markers: this.mapLayerData(json) 
     }), 
     err => { 
      // handle errors 
     } 
    ) 
    } 

    // store only the data you want to pass as props to each Marker 
    // instead of mapping it directly in MapChart every time it renders 
    mapLayerData(markers) { 
    // use a standard map function instead of $.each 
    // destructuring saves time and repetition 
    return markers.map(({ category, location }) => ({ 
     // use a template string and a simple map of icon names to get your icon uri 
     icon: 'http://maps.google.com/mapfiles/ms/icons/'+ iconMap[category] +'.png', 
     label: category, 
     name: category, 
     position: { 
     lat: location.latitude, 
     lng: location.longitude 
     } 
    })) 
    } 

    render() { 
    // there's only one layer, so render it directly 
    return (
     <div className="app"> 
     <MapChart markers={this.state.markers} /> 
     </div> 
    ) 
    } 
} 



function mapStateToProps(state){ 
    return { 
    posts: state.posts 
    } 
} 


let Container = connect(mapStateToProps, {fetchPostsWithRedux})(CrimeMap); 

const store = createStore(
    reducer, 
    applyMiddleware(thunk) 
); 


//https://data.police.uk/docs/method/crime-street/ 
render(
    <Provider store={store}> 
     <Container/> 
    </Provider>, 
    document.getElementById('root') 
); 
+0

發佈您嘗試過的redux實現(如果不是,請從[此處](http://redux.js.org/docs/introduction/index.html)開始)將吸引更多幫助。 –

+0

它可以是其中一種 - 實現或不是 - 種情況。我寧願看看它如何幹淨地完成,爲什麼 - 然後只是推了什麼東西 –

+0

有[例子](https://github.com/reactjs/redux#examples),你可以參考看看它如何幹淨地完成,和有許多着名的樣板。 Redux是一個[概念](http://redux.js.org/docs/introduction/CoreConcepts.html)和一組可用於管理應用程序狀態的API。您可以選擇適合您的任何實施方案,並且滿足您的需求。 –

回答

1

這裏是您有共享 1.當部件安裝件,它調用一個功能 2.此功能 「fetchPostsWithRedux」,則該代碼的流程也發送動作,它發送一個API調用服務器來獲取數據。 3.當數據被接收時,組件重新呈現更新後的數據作爲道具。

現在,如果你想使用mapLayerData功能,給數據的組件,而無需使用「舊取方法」,你可以做以下

提到增加一個功能命名componentWillReceiveProps

componentWillReceiveProps(nextProps){ 

    this.setState({markers: this.mapLayerData(nextProps.posts)}); 

} 

一旦你調用這個,組件的狀態現在會有我們從api調用收到的數據

希望上面的解決方案已經給出了一些清晰的說明。

+0

這就是我現在正在進行的 - http://jsfiddle.net/0ht35rpb/98/ –

+0

我需要你的援助註冊表格 - https://stackoverflow.com/questions/45942891/reactjs-redux-storing-data-from-a-form-submission –