我正在开发一个以本机响应的应用程序,在屏幕之间导航时,我需要停止/取消redux saga。我该怎么办?
我需要这个,因为我想避免过渡时出现延迟。 您可以观看视频,以更好地了解我的观点https://streamable.com/45qsa
我的代码在下面。
MindfulnessScreen.js
class MindFulness extends Component {
componentDidMount() {
this.props.dispatch(getMindFulness());
this.props.dispatch(toggleBottomBar(true));
}
render() {
const { isFetchingData, mindfulnessData, isLoggedIn, userType } = this.props;
const header = mindfulnessData.header;
const subHeader = mindfulnessData.subheader;
const imageBanner = FILES_URL + mindfulnessData.image_banner;
const mindFulnessDatas = mindfulnessData.children;
return (
<View style={{ flex: 1, backgroundColor: '#1F1F20' }}>
{isFetchingData && <LoadingIndicator />}
{/* <BottomBar screen={'MindFulness'} navigation={this.props.navigation} /> */}
<ScrollView style={{ flexGrow: 1, marginBottom: 35 }}>
{!isFetchingData && <FastImage
style={{
width: '100%',
height: 137,
display: "flex",
alignItems: "center",
}}
resizeMode={FastImage.resizeMode.cover}
source={{ uri: imageBanner }}
>
<View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, justifyContent: 'center', alignItems: 'center', paddingLeft: 30, paddingRight: 30 }}>
<Text style={{
textAlign: 'center',
fontSize: 20,
color: '#FFFFFF',
fontFamily: Theme.FONT_BOLD
}}>{header}</Text>
<Text style={{
textAlign: 'center',
fontSize: 14,
paddingTop: 8,
color: '#FFFFFF',
fontFamily: Theme.FONT_MEDIUM
}}>{subHeader}</Text>
</View>
</FastImage>}
{this.renderData(mindFulnessDatas)}
{!isFetchingData && isLoggedIn && userType == 0 && <View style={{
width: width,
height: 200,
marginBottom: 30,
borderRadius: 12,
shadowRadius: 16,
shadowOffset: { width: 0, height: 8 },
shadowColor: "black",
shadowOpacity: 0.47,
elevation: 2
}}
>
<FastImage style={{ width: '100%', height: '100%' }} source={unlockActivitiesBannerImage}>
<View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{
fontSize: 20,
color: '#FFFFFF',
textAlign: 'center',
position: 'absolute',
top: 40,
fontFamily: Theme.FONT_BOLD
}}>{'All Synesthesia Meditations \n 7 days for free'}</Text>
<CustomButton
disabled={false}
style={{
height: 50,
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
marginTop: 45,
width: 230,
borderRadius: 45,
backgroundColor: '#25B999',
opacity: 1
}}
title="Start free trial"
onPress={() => {
this.props.dispatch(setMenuItem('7 days for free'))
this.props.navigation.navigate('Pricing')
}}
/>
</View>
</FastImage>
</View>}
</ScrollView>
</View>
)
}
}
function mapStateToProps(state) {
return {
isFetchingData: state.mindfulnessReducer.isFetchingData,
mindfulnessData: state.mindfulnessReducer.mindfulnessData
}
}
export default connect(mapStateToProps)(MindFulness);
AwarenessScreen与MindfulnessScreen.js相似
MindFulnessAction.js
import { ActionTypes } from '../constants/constants'
export function getMindFulness() {
return {
type: ActionTypes.GET_MINDFULNESS,
payload: {}
}
}
mindulnessReducer.js
import { ActionTypes } from '../constants/constants'
const initialState = {
error: false,
isFetchingData: false,
mindfulnessData: [],
};
export const mindfulnessReducer = (state = initialState, action) => {
switch (action.type) {
case ActionTypes.GET_MINDFULNESS:
return {
...state,
isFetchingData: true
}
case ActionTypes.GET_MINDFULNESS_SUCCESS:
return {
...state,
isFetchingData: false,
mindfulnessData: action.payload.node
}
case ActionTypes.GET_MINDFULNESS_FAIL:
return {
...state,
error: true,
isFetchingData: false
}
default:
return state
}
}
api.js
let commonHeaders = {
'Content-Type': 'application/json',
}
export const getMindFulness = (token) => fetch(`${baseUrl}node/337?token=${token}`, {
method: 'GET',
headers: {
...commonHeaders,
},
}).then(response => response.json());
mindFulnessSaga.js
import { AsyncStorage } from 'react-native';
import { put, call, select } from 'redux-saga/effects'
import { ActionTypes } from '../constants/constants'
import { getMindFulness, getMindFulnessAnonymous } from '../api/api'
export const getMindfulnessData = (state) => state.mindfulnessReducer.mindfulnessData;
const MindFulnessSaga = function* (action) {
const token = yield AsyncStorage.getItem('token');
const mindfulnessData = yield select(getMindfulnessData);
// if (mindfulnessData.length == 0) {
if (token !== null) {
const dataObject = yield call(getMindFulness, token);
if (dataObject.status.success) {
yield put({
type: ActionTypes.GET_MINDFULNESS_SUCCESS,
payload: {
...dataObject
}
})
}
else {
yield put({
type: ActionTypes.GET_MINDFULNESS_FAIL
})
}
}
else {
const dataObject = yield call(getMindFulnessAnonymous);
yield put({
type: ActionTypes.GET_MINDFULNESS_SUCCESS,
payload: {
...dataObject
}
})
}
// }
}
export default MindFulnessSaga
rootSaga.js
import { takeLatest } from 'redux-saga/effects'
import { ActionTypes } from '../constants/constants'
import MindFulnessSaga from './MindFulnessSaga'
import BeingAwareSaga from './BeingAwareSaga'
const rootSaga = function* () {
yield takeLatest(ActionTypes.GET_MINDFULNESS, MindFulnessSaga)
yield takeLatest(ActionTypes.GET_BEINGAWARE, BeingAwareSaga)
}
export default rootSaga
有什么建议吗?
谢谢
答案 0 :(得分:2)
我的原始答案(我留在下面)不正确。我在谈论takeLatest
效果时犯了一个错误,因为像the docs say
在分配给与模式匹配的商店的每个动作上产生传奇。 并自动取消,如果它仍在运行,则以前启动的任何先前的传奇任务。
因此,先前的MindFulnessSaga
/ BeingAwareSaga
被takeLatest
效果自动取消。这并不意味着如果要取消以前的AJAX调用,也需要取消AJAX调用。
您可以通过将所有代码都放在try / final中并在finally
块中对其进行管理,以管理传奇取消
import { cancelled } from 'redux-saga/effects'
function* MindFulnessSaga() {
try {
// ... your code
} finally {
if (yield cancelled())
// the saga has been cancelled, cancel the AJAX request too
}
}
这就是说:导航滞后可能与您没有缓存AJAX响应有关(但您在开始时就已经做了,因为您已经注释了// if (mindfulnessData.length == 0) {
块)。
您需要:
请查看this answer of mine,以获取逐步说明。
让我知道您是否需要更多帮助