Reactjs 导航时如何停止/取消redux saga
我正在用react native开发一个应用程序,在屏幕之间导航时需要停止/取消redux传奇。我怎样才能做到这一点 我之所以需要这个,是因为我想避免过渡时的滞后。 你可以看视频来更好地理解我的观点 我的代码如下 MindfulnessScreen.jsReactjs 导航时如何停止/取消redux saga,reactjs,react-native,redux,react-redux,redux-saga,Reactjs,React Native,Redux,React Redux,Redux Saga,我正在用react native开发一个应用程序,在屏幕之间导航时需要停止/取消redux传奇。我怎样才能做到这一点 我之所以需要这个,是因为我想避免过渡时的滞后。 你可以看视频来更好地理解我的观点 我的代码如下 MindfulnessScreen.js class MindFulness extends Component { componentDidMount() { this.props.dispatch(getMindFulness()); this.props.
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);
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());
Mindfulnessaga.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
有什么建议吗
谢谢你我原来留下的答案不正确。我在谈论最新的效果时犯了一个错误,因为 在发送到存储区的每个与模式匹配的操作上产生传奇。并自动取消以前启动的任何saga任务(如果它仍在运行) 因此,之前的MindFulnessSaga/BeingAwareSaga会被最新效果自动取消。这并不意味着AJAX调用也被取消,如果您想要取消之前的AJAX调用,您需要自己管理取消 您可以通过将其所有代码放入try/finally并在finally块中管理来管理传奇取消 这就是说:导航上的延迟可能与这样一个事实有关:您没有缓存AJAX响应,但在开始时就缓存了,因为您已经对//if mindfulnessData.length==0{block进行了注释 原始答案 您需要: 用自定义无限循环替换最新的循环 用叉子叉出不同的传奇故事,以便以后可以取消它们 当用户导航到另一个屏幕时,取消分叉传奇 请参阅以获得逐步的解释
如果您需要更多帮助,请告诉我我在下面留下的原始答案不正确。我在谈论最新效果时犯了一个错误,因为 在发送到存储区的每个与模式匹配的操作上生成一个传奇。如果之前启动的任何传奇任务仍在运行,则会自动取消该任务 所以之前的MindFulnessSaga/BeingAwareSaga会被TakeLast effect自动取消。这并不意味着AJAX调用也会被取消,如果你想取消之前的AJAX调用,你需要自己管理取消 您可以通过将其所有代码放入try/finally并在finally块中管理来管理传奇取消 这就是说:导航上的延迟可能与这样一个事实有关:您没有缓存AJAX响应,但在开始时就缓存了,因为您已经对//if mindfulnessData.length==0{block进行了注释 原始答案 您需要: 用自定义无限循环替换最新的循环 用叉子叉出不同的传奇故事,以便以后可以取消它们 当用户导航到另一个屏幕时,取消分叉传奇 请参阅以获得逐步的解释
如果您需要更多帮助,请告诉我。非常感谢您的回答。我集成了fork和cancel,但他们没有做到这一点。我怀疑这最终可能是一个redux操作。您可以在codesandbox上共享它吗?或者转换为标准react站点需要很长时间吗?这样做很耗时,但可能我会尝试使用mi它的真实版本。还有一个问题:你有没有尝试缓存取消长度检查注释的响应?@thodwris?你有没有做更多的尝试?非常感谢你的回答。我集成了fork和cancel,但他们没有这样做。我怀疑这最终可能是一个redux操作。你能在codesandbox上共享它吗?还是很长要转换为标准react站点?这样做很耗时,但我可能会尝试使用它的最低版本。还有一个问题:您是否尝试过缓存响应以取消长度检查的注释?@thodwris?您是否进行了更多尝试?
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
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
}
}