使用localstorage时,映射状态不会保留

时间:2016-12-17 05:20:01

标签: javascript reactjs local-storage redux react-redux

我有一个应用程序,用户可以搜索汽车并查看结果。结果页面包含汽车的结果以及地图(根据搜索显示源到目的地)。当我刷新页面时,汽车结果的状态被保留并且它运行良好但我得到一个错误的地图作为无效的latlng并且也没有显示到目的地路线的源。我在redux中使用了persistedState。

这是我的代码

localstorage.js

export const loadState = () => {
  try {
    const serializedState = localStorage.getItem('state');
    if (serializedState === null) {
      return undefined;
    }
    return JSON.parse(serializedState);
  } catch (err) {
    return undefined;
  }
};

export const saveState = (state) => {
  try {
    const serializedState = JSON.stringify(state);
    localStorage.setItem('state', serializedState);
  } catch (err) {
    // Ignore write errors
  }
};

index.js

store.subscribe(() => {
  saveState({
    getCarResult: store.getState().getCarResult,
    locale: store.getState().locale,
  });
});

轿厢result.js

function renderMap(cityOrigenLat, cityOrigenLng, cityDestinoLat, cityDestinoLng) {
  return (
        <GoogleMap
          cityOrigenLat={cityOrigenLat}
          cityOrigenLng={cityOrigenLng}
          cityDestinoLat={cityDestinoLat}
          cityDestinoLng={cityDestinoLng}
        />
      );
}

const GoogleMap = ({ cityOrigenLat, cityOrigenLng, cityDestinoLat, cityDestinoLng }) => {
  console.log('cityOrigenLat', cityOrigenLat);
  const position = cityOrigenLat ? [cityOrigenLat, cityOrigenLng] : [51.505, -0.09];
  const icon = divIcon({
    className: 'car-icon',
    iconSize: [50, 50]
  });

  return (
    <Map center={position} zoom={5} style={{ height: 600 }}>
      <TileLayer
        url='https://mt{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}'
        subdomains='0123'
      />
      <Marker position={[cityOrigenLat, cityOrigenLng]} icon={icon} />
      <Marker position={[cityDestinoLat, cityDestinoLng]} icon={icon} />
      <CarRouting from={[cityOrigenLat, cityOrigenLng]} to={[cityDestinoLat, cityDestinoLng]} />
    </Map>
  );
};

class CarResult extends Component {
  render() {
    const { carResult, origen, destino, page, locale } = this.props;
    const cityOrigen = origen && origen.label.split(', ')[0];
    const cityOrigenLat = origen && origen.location.lat; // undefined when refreshing the page 
    const cityOrigenLng = origen && origen.location.lng;
    const cityDestino = destino && destino.label.split(', ')[0];
    const cityDestinoLat = destino && destino.location.lat;
    const cityDestinoLng = destino && destino.location.lng;
    const carResultList = renderCarList(
                          carResult.cars, cityOrigen, cityDestino,
                          startIndex, startCount, perPage, locale
                        );
    const carResultMap = renderMap(cityOrigenLat, cityOrigenLng, cityDestinoLat, cityDestinoLng);
    if (!carResult.fetching) {
      return (
        <div>
          Hemos encontrado {carResultList.length} ofertas para ti.
          <div className="car-result-container">
            <Grid fluid>
              <Row>
                <Col xs={12} sm={12} md={6}>
                  {carResultList}
                </Col>
                <Col x={12} sm={12} md={6} className="kolabooMap">
                  {carResultMap}
                </Col>
              </Row>
            </Grid>
          </div>
        </div>
      );
    }
    return (
      <Grid fluid>
        <Row>
          <Col xs={12} sm={12} md={6}>
            <Row>
              <Col xs={12} sm={12} md={6}>
                loading ...
              </Col>
            </Row>
          </Col>
        </Row>
      </Grid>
    );
  }
  changePage(page) {
    console.log('page', page);
      this.props.dispatch(push('/car/?page=' + page));
  }
}

function mapStateToProps(state) {
  return {
     page: Number(state.routing.locationBeforeTransitions.query.page) || 1,
     locale: state.locale
  };
}

export default connect(mapStateToProps)(CarResult);

轿厢routing.js

class CarRouting extends MapLayer {
  componentWillMount() {
    super.componentWillMount();
    const { map, from, to, ...props } = this.props;
    props.icon = L.divIcon({
        className: 'car-icon',
        iconSize: [50, 50]
    });
    this.leafletElement =
      L.Routing.control({
      position: 'topleft',
      createMarker: () => null,
      waypoints: [
        L.latLng(from[0], from[1]),
        L.latLng(to[0], to[1]),
      ],
    }).addTo(map);
    // L.marker(position, props);
  }

  render() {
    return null;
  }
}

export default CarRouting;

结果-layout.js

<CarResult
  origen={Origen}
  destino={Destino}
  carResult={carResult}
/>

const mapStateToProps = state => {
    console.log('state', state);
    const carValues = selector(state, 'Origen', 'Destino', 'daterange');
    return {
        carValues,
        carResult: state.getCarResult
    };
  };

问题是当我刷新页面时,会显示汽车的结果(状态被保留)但路由没有显示在地图中,因为我收到错误

Uncaught Error: Invalid LatLng object: (undefined, undefined). I get cityOrigenLat undefined during refreshing the page

更新

let cars = [];
const initialState = {
  fetching: false,
  fetched: true,
  cars: [],
  currentPage: 0,
  carsLength: 0,
  error: null
};

export function getCarResult(state = initialState, action) {
  switch (action.type) {
    case 'CAR_FETCH_START':
      return { ...state, fetching: true };
    case 'CAR_FETCH_SUCCESS':
      cars = action.payload;
      return {
              ...state,
              fetched: true,
              fetching: false,
              cars: action.payload,
              currentPage: 0,
              carsLength: action.payload.length
             };
    case 'CAR_FETCH_WITH_FILTER':
      return { ...state, fetched: true, fetching: false, cars: carFilterFromPrice(action.payload) };
    case 'CAR_FETCH_WITH_TIME_FILTER':
      return { ...state, fetched: true, fetching: false, cars: carFilterFromTime(action.payload) };
    case 'CAR_FETCH_FAILURE':
      return { ...state, error: action.payload };
    default:
      return state;
  }
}

0 个答案:

没有答案