development

성공적인 비동기 redux 작업시 다른 경로로 전환

big-blog 2020. 12. 25. 22:47
반응형

성공적인 비동기 redux 작업시 다른 경로로 전환


매우 간단한 반응 구성 요소 세트가 있습니다.

  • containerredux에 연결되어 작업, 스토어 구독 등을 처리합니다.
  • list 내 항목 목록을 표시합니다
  • new 목록에 새 항목을 추가하는 양식입니다.

나는 일부가 반응 라우터 경로는 다음과 같이 :

<Route name='products' path='products' handler={ProductsContainer}>
  <Route name='productNew' path='new' handler={ProductNew} />
  <DefaultRoute handler={ProductsList} />
</Route>

list또는 둘 중 하나만 표시되도록합니다 form.

내가하고 싶은 것은 새 항목이 성공적으로 추가되면 응용 프로그램이 목록으로 다시 라우팅되도록하는 것입니다.

지금까지 내 솔루션 .then()은 async 후 있습니다 dispatch.

dispatch(actions.addProduct(product)
  .then(this.transitionTo('products'))
)

이것이 올바른 방법입니까, 아니면 경로 변경을 트리거하는 다른 작업을 수행해야합니까?


이 같은보다 완벽한 솔루션을 사용하지 않을 경우 돌아 오는 라우터 , 당신은 사용할 수 있습니다 돌아 오는 역사 전환 이 같은 코드를 작성할 수 있습니다 :

export function login() {
  return {
    type: LOGGED_IN,
    payload: {
      userId: 123
    }
    meta: {
      transition: (state, action) => ({
        path: `/logged-in/${action.payload.userId}`,
        query: {
          some: 'queryParam'
        },
        state: {
          some: 'state'
        }
      })
    }
  };
}

이것은 당신이 제안한 것과 비슷 하지만 조금 더 정교합니다. 여전히 내부에서 동일한 히스토리 라이브러리를 사용 하므로 React Router와 호환됩니다.


대략 다음과 같은 매우 간단한 미들웨어를 만들었습니다.

import history from "../routes/history";

export default store => next => action => {

    if ( ! action.redirect ) return next(action);

    history.replaceState(null, action.redirect);
}

따라서 거기에서 successful행동에 redirect속성 있는지 확인하기 만하면 됩니다. 또한이 미들웨어는 next(). 이것은 경로 전환이 액션 체인의 끝이되어야하기 때문에 의도 된 것입니다.


미들웨어 API 레이어를 사용하여 isomorphic-fetch 와 같은 사용을 추상화하고 redux-thunk를 사용 dispatch하는 경우 다음과 같이 작업 내에서 Promise 를 연결 하면됩니다.

import { push } from 'react-router-redux';
const USER_ID = // imported from JWT;

function fetchUser(primaryKey, opts) {
    // this prepares object for the API middleware
}

// this can be called from your container
export function updateUser(payload, redirectUrl) {
    var opts = {
        method: 'PUT',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(payload)
    };
    return (dispatch) => {
        return dispatch(fetchUser(USER_ID, opts))
            .then((action) => {
                if (action.type === ActionTypes.USER_SUCCESS) {
                    dispatch(push(redirectUrl));
                }
            });
    };
}

이렇게하면 여기제안 된대로 코드에 라이브러리를 추가 할 필요가 줄어들고 redux-history-transitions 에서 수행 된대로 리디렉션과 함께 작업을 멋지게 배치 할 수 있습니다 .

내 가게는 다음과 같습니다.

import { createStore, applyMiddleware } from 'redux';
import rootReducer from '../reducers';
import thunk from 'redux-thunk';
import api from '../middleware/api';
import { routerMiddleware } from 'react-router-redux';

export default function configureStore(initialState, browserHistory) {
    const store = createStore(
        rootReducer,
        initialState,
        applyMiddleware(thunk, api, routerMiddleware(browserHistory))
    );

    return store;
}

react-navigation이 이미 react-native 문서에 포함되어 있기 때문에 파티에 조금 늦었 음을 알고 있지만 여전히 앱에서 Navigator api를 사용 / 사용한 사용자에게는 유용 할 수 있습니다. 내가 시도한 것은 약간 hackish, renderScene이 발생하자마자 내비게이터 인스턴스를 객체에 저장하고 있습니다.

renderScene(route, navigator) {
      const Component = Routes[route.Name]
      api.updateNavigator(navigator); //will allow us to access navigator anywhere within the app
      return <Component route={route} navigator={navigator} data={route.data}/>

}

my api file is something lke this

'use strict';

//this file includes all my global functions
import React, {Component} from 'react';
import {Linking, Alert, NetInfo, Platform} from 'react-native';
var api = {
    navigator,
    isAndroid(){
        return (Platform.OS === 'android');
    },
    updateNavigator(_navigator){
      if(_navigator)
          this.navigator = _navigator;
    },
}

module.exports = api;

now in your actions you can simply call

api.navigator.push({Name:'routeName', data:WHATEVER_YOU_WANTED_TO_PASS)

you just need to import your api from the module.


If you're using react-redux and react-router, then I think this link provides a great solution.

Here's the steps I used:

  • Pass in a react-router history prop to your component, either by rendering your component inside a react-router <Route/> component or by creating a Higher Order Component using withRouter.
  • Next, create the route you want to redirect to (I called mine to).
  • Third, call your redux action with both history and to.
  • Finally, when you want to redirect (e.g., when your redux action resolves), call history.push(to).

ReferenceURL : https://stackoverflow.com/questions/32612418/transition-to-another-route-on-successful-async-redux-action

반응형