Я создаю проект с react-redux
, в моем проекте много городов, щелкните каждый из городов, чтобы перейти к компоненту моего класса TheaterList.js
Я установил, что у моего редуктора есть флаг loading
(по умолчанию true
при успешном извлечении данных, затем вернуть их с false
) с моим действием MOVIELIST_THEATER
, вот мой код MovieListReducer.js
:
import {
MOVIELIST_MAINACTIVITY,
MOVIELIST_THISWEEK,
MOVIELIST_THEATER,
MOVIELIST_TIME,
MOVIE_DETAIL
} from '../actions/types';
const INITIAL_STATE = {
mainMovie: [],
thisWeek: [],
theaterList: [],
timeList: [],
movieDetail: [],
loading: true
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case MOVIELIST_MAINACTIVITY:
return {
...state,
mainMovie: action.payload
};
case MOVIELIST_THISWEEK:
return {
...state,
thisWeek: action.payload
};
case MOVIELIST_THEATER:
return {
...state,
theaterList: action.payload,
loading: false
};
case MOVIELIST_TIME:
return {
...state,
timeList: action.payload
};
case MOVIE_DETAIL:
return {
...state,
movieDetail: action.payload
};
default:
return state;
}
};
А вот мой компонент класса TheaterList.js
:
import React, { Component } from 'react';
import { View, Text, FlatList } from 'react-native';
import { ListItem } from 'react-native-elements';
import { connect } from 'react-redux';
import { fetchTheater } from '../actions';
import { Spinner } from './common';
class TheaterList extends Component {
constructor(props) {
super(props);
this.renderItem = this.renderItem.bind(this);
const { enCity } = this.props.navigation.state.params;
this.state = {
navigation: this.props.navigation,
enCity
};
}
componentDidMount() {
this.props.fetchTheater({ enCity: this.state.enCity });
}
renderItem({ item }) {
// some view tag
}
render() {
const theaters = this.props.theaterList;
// the default is true when fetch data succeed then return it with false
if (this.props.loading) {
return (
<Spinner text='Loading...' />
);
}
return (
<View style={{ flex: 1 }}>
<FlatList
data={theaters}
renderItem={this.renderItem}
numColumns={1}
horizontal={false}
keyExtractor={(item, index) => index.toString()}
/>
</View>
);
}
}
const mapStateToProps = (state) => {
const theaterList = state.listType.theaterList;
const loading = state.listType.loading;
return { theaterList, loading };
};
const styles = {
// some style settings
};
export default connect(mapStateToProps, { fetchTheater })(TheaterList);
Сначала он работает очень хорошо, например, показывает, что <Spinner />
ждет, пока состояние возврата и повторного рендеринга данных покажет мой <FlatList />
, но когда я вернусь к экрану иперейдите к TheaterList.js
снова, я нахожу this.props.loading
значение по-прежнему false
.Это приводит к тому, что мой <Spinner />
не будет отображаться.
Я пытаюсь контролировать флаг загрузки, добавив this.props.loading = true;
в функцию componentDidMount()
.Очевидно, что это неправильно.
Вот мой action.js
:
import {
MOVIELIST_MAINACTIVITY,
MOVIELIST_THISWEEK,
MOVIELIST_THEATER,
MOVIELIST_TIME,
MOVIE_DETAIL
} from './types';
export const fetchMainMovieList = () => {
return (dispatch) => {
fetch('https://obscure-reaches-65656.herokuapp.com/api?city=Taipei&theater=Centuryasia')
.then(response => response.json())
.then(responseData => {
dispatch({ type: MOVIELIST_MAINACTIVITY, payload: responseData[0].movie });
})
.catch((error) => console.log(error));
};
};
export const fetchThisWeek = () => {
return (dispatch) => {
fetch('https://obscure-reaches-65656.herokuapp.com/api/thisWeek')
.then(response => response.json())
.then(responseData => {
dispatch({ type: MOVIELIST_THISWEEK, payload: responseData[0].movie });
})
.catch((error) => console.log(error));
};
};
export const fetchTheater = ({ enCity }) => {
return (dispatch) => {
fetch(`https://obscure-reaches-65656.herokuapp.com/api/drivers?city=${enCity}&lng=121.584065&lat=25.041317`)
.then(response => response.json())
.then(responseData => {
console.log(responseData);
dispatch({ type: MOVIELIST_THEATER, payload: responseData });
})
.catch((error) => console.log(error));
};
};
export const fetchTime = ({ enCity, theater }) => {
return (dispatch) => {
fetch(`https://obscure-reaches-65656.herokuapp.com/api?city=${enCity}&theater=${theater}`)
.then(response => response.json())
.then(responseData => {
dispatch({ type: MOVIELIST_TIME, payload: responseData[0].movie });
})
.catch((error) => console.log(error));
};
};
export const fetchDetail = ({ enCity, cnName }) => {
return (dispatch) => {
fetch(`https://obscure-reaches-65656.herokuapp.com/api/detail?city=${enCity}&movie=${cnName}`)
.then(response => response.json())
.then(responseData => {
dispatch({ type: MOVIE_DETAIL, payload: responseData[0].movie });
})
.catch((error) => console.log(error));
};
};
Так как именно установить флаг loading
с react-redux
, если использовать тот же компонент класса?
Любая помощь будет оценена.Заранее спасибо.
В соответствии с рекомендациями @MRFrhn я внесу некоторые изменения.
В моем action.js
добавьте dispatch({ type: MOVIE_REQUEST_THEATER });
перед извлечением данных:
export const fetchDetail = ({ enCity, cnName }) => {
return (dispatch) => {
dispatch({ type: MOVIE_REQUEST_THEATER });
fetch(`https://obscure-reaches-65656.herokuapp.com/api/detail?city=${enCity}&movie=${cnName}`)
.then(response => response.json())
.then(responseData => {
dispatch({ type: MOVIE_DETAIL, payload: responseData[0].movie });
})
.catch((error) => console.log(error));
};
};
ВМой редуктор добавляет регистр:
case MOVIE_REQUEST_THEATER:
console.log('MOVIE_REQUEST_THEATER');
return {
...state,
loading: true, // show the spinner
};
Я думаю, что это должно быть успешно, потому что я возвращаю loading
flag true
до получения данных, но это не работает, тогда я вижу свой журнал, console.log('MOVIE_REQUEST_THEATER');
не показываетсяНе знаю почему ...