使用redux在组件内部反应原生get状态

时间:2018-02-25 12:47:22

标签: javascript react-native redux

我正在使用openweathermap的api制作天气应用程序。我有一个搜索按钮(在SearchScreen.js内),当按下时调用fetchWeatherData(cityName)(城市名称从this.state.searchQuery传递,其中取值为textinput)。 问题是我使用调度操作获得多个错误,并通过redux更新状态。有人可以帮帮我吗。 我的代码:

Actions.js:

    import { getWeatherByName } from '../../constants/api';

    export const FETCH_WEATHER_BY_CITY = 'FETCH_WEATHER_BY_CITY';
    export const FETCH_WEATHER_BY_CITY_PENDING = 
       'FETCH_WEATHER_BY_CITY_PENDING';
    export const FETCH_WEATHER_BY_CITY_SUCCESS = 
       'FETCH_WEATHER_BY_CITY_SUCCESS';
    export const FETCH_WEATHER_BY_CITY_ERROR = 
       'FETCH_WEATHER_BY_CITY_ERROR';

    export const fetchWeather = (cityName) => ({
       type: FETCH_WEATHER_BY_CITY,
       payload: getWeatherByName(cityName),
    });

Reducer.js(在屏幕文件夹中):

import {
  FETCH_WEATHER_BY_CITY_PENDING,
  FETCH_WEATHER_BY_CITY_ERROR,
  FETCH_WEATHER_BY_CITY_SUCCESS,
} from './actions';

const initialState = {
  data: [],
  fetching: false,
  fetched: false,
  error: null,
};

export const weatherReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_WEATHER_BY_CITY_SUCCESS:
      return {
        data: [...state.data, action.payload],
        fetching: false,
        fetched: true,
        error: null,
      };
    case FETCH_WEATHER_BY_CITY_PENDING:
      return {
        data: [...state.data],
        fetching: true,
        fetched: false,
        error: null,
      };

    case FETCH_WEATHER_BY_CITY_ERROR:
      return {
        data: [...state.data],
        fetching: false,
        fetched: true,
        error: 'An Error occured',
      };
    default:
      return state;
  }
};

Reducer.js(组合reducer的主文件):

import { combineReducers } from 'redux';

import {
  weatherReducer,
} from '../search/reducer';

export default combineReducers({
  weather: weatherReducer,
});

Store.js:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

import reducers from './reducer';

const middlewares = [
  thunk,
];

if (__DEV__) { // eslint-disable-line
  const { createLogger } = require('redux-logger');

  middlewares.push(createLogger());
}

export default createStore(
  reducers,
  applyMiddleware(...middlewares)
);

SearchScreen.js:

import React, { Component } from 'react';
import {
  View,
  Button,
  TextInput,
  TouchableOpacity,
} from 'react-native';
import { Ionicons, EvilIcons } from '@expo/vector-icons';
import { connect } from 'redux';

import { fetchWeather } from './actions';
import CityItem from './CityItem';
import Colors from '../../constants/Colors';
import styles from './styles/SearchScreen';

class SearchScreen extends Component {
  static navigationOptions = ({ navigation }) => ({
    title: 'Add Locations',
    headerLeft: (
      <TouchableOpacity style={styles.backButton}>
        <Ionicons
          name='ios-arrow-back'
          size={30}
          onPress={() => navigation.goBack()}
        />
      </TouchableOpacity>
    ),
    headerRight: (
      <TouchableOpacity>
        <EvilIcons
          name='location'
          size={30}
        />
      </TouchableOpacity>
    ),
  });

  state = {
    searchQuery: '',
  }

  fetchWeatherData = (cityName) => {
    this.props.fetchWeather(cityName);
  }

  render() {
    const {
      data,
      fetching,
      fetched,
      error,
    } = this.props;

    return (
      <View style={styles.root}>
        <View style={styles.topContainer}>
          <View style={{ flex: 1, flexDirection: 'row' }}>
            <TextInput
              style={styles.searchBox}
              placeholder='Search for a place'
              placeholderTextColor={Colors.$blackColor}
              padding={5}
              autoCorrect={false}
              onChangeText={(searchQuery) => this.setState({ searchQuery })}
            />
            <Button
              onPress={this.fetchWeatherData}
              title='Search'
              style={styles.searchButton}
            />
          </View>
        </View>
        <View style={styles.bottomContainer}>
          {!this.state.loading && this.state.searchedYet && <CityItem data={this.state.data} /> }
        </View>

      </View>
    );
  }
}

const mapStateToProps = (state) => ({
  data: state.weather.data,
  fetched: state.weather.fetched,
  fetching: state.weather.fetching,
  error: state.weather.error,
});

const mapDispatchToProps = (dispatch) => ({
  fetchWeather: dispatch(fetchWeather(this.state.searchQuery)),
});

export default connect(mapStateToProps, mapDispatchToProps)(SearchScreen);

我没有得到任何结果,应用程序因每次不同的原因而崩溃。请帮忙!

0 个答案:

没有答案