Как остановить / отменить саксофон при навигации - PullRequest
0 голосов
/ 07 апреля 2019

Я занимаюсь разработкой приложения на реагирующем языке, и мне нужно останавливать / отменять сагу примитивов при навигации между экранами. Как мне это сделать?

Мне это нужно, потому что я хочу избежать задержки при переходе. Вы можете посмотреть видео, чтобы поправиться моя точка 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

Любые рекомендации?

Спасибо

1 Ответ

2 голосов
/ 09 апреля 2019

Мой оригинальный ответ (я оставил его ниже) был неверным. Я допустил ошибку, говоря об эффекте takeLatest, потому что, как говорят в документах,

Создает сагу о каждом действии, отправляемом в Магазин, которое соответствует шаблону. И автоматически отменяет любую предыдущую задачу саги, запущенную ранее, если она все еще выполняется.

Таким образом, предыдущий MindFulnessSaga / BeingAwareSaga автоматически отменяется эффектом takeLatest. Это не означает, что вызовы AJAX также отменяются, если вы хотите отменить предыдущие вызовы AJAX, вам нужно самостоятельно управлять отменой.

Вы можете управлять отменой саги, поместив весь ее код в try / finally и управляя им в блоке 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) {).



ОРИГИНАЛЬНЫЙ ОТВЕТ

Вам необходимо:

  • заменить takeLatest пользовательским бесконечным циклом ( docs )
  • fork ( документы ) различные саги, чтобы вы могли cancel ( документы ) их позже
  • cancel раздвоенные саги, когда пользователь переходит на другой экран

Посмотрите на этот мой ответ для пошагового объяснения.

Дайте мне знать, если вам нужна дополнительная помощь ?

...