programing

리액트 라우터의 루트 천이에 대한 응답으로 Redx 액션을 기동하다

bestprogram 2023. 2. 26. 16:25

리액트 라우터의 루트 천이에 대한 응답으로 Redx 액션을 기동하다

최신 앱에서 리액트 라우터와 리덕스를 사용하고 있으며, 현재 url 파라미터와 쿼리에 따라 상태 변경과 관련된 몇 가지 문제에 직면해 있습니다.

기본적으로 URL이 변경될 때마다 상태를 업데이트해야 하는 컴포넌트가 있습니다.이렇게 장식가와의 레덕스로 소품을 통해 주를 넘기고 있다.

 @connect(state => ({
   campaigngroups: state.jobresults.campaigngroups,
   error: state.jobresults.error,
   loading: state.jobresults.loading
 }))

현재 componentWillReceiveProps 라이프 사이클 메서드를 사용하여 리액트라우터로부터의 URL 변경에 응답하고 있습니다.리액트 라우터는 이 . props . params this this . props this this thiss.props this in in in in in in in in in in in.query - 이 접근법의 주요 문제는 이 방법으로 상태를 갱신하기 위한 액션을 실행한다는 것입니다.그러면 같은 라이프 사이클 방식을 다시 트리거하는 컴포넌트에 새로운 소품이 전달되고, 기본적으로 무한 루프가 생성되며, 현재 이 일이 발생하지 않도록 상태 변수를 설정하고 있습니다.

  componentWillReceiveProps(nextProps) {
    if (this.state.shouldupdate) {
      let { slug } = nextProps.params;
      let { citizenships, discipline, workright, location } = nextProps.query;
      const params = { slug, discipline, workright, location };
      let filters = this._getFilters(params);
      // set the state accroding to the filters in the url
      this._setState(params);
      // trigger the action to refill the stores
      this.actions.loadCampaignGroups(filters);
    }
  }

루트 전환을 기반으로 액션을 트리거하는 표준 접근법이 있습니까? 아니면 스토어를 소품을 통과시키지 않고 컴포넌트 상태에 직접 연결할 수 있습니까?will Transition To static 메서드를 사용하려고 했지만, 그곳에서는 this.props.dispatch에 액세스할 수 없습니다.

알겠습니다, 리덕스 github 페이지에서 답을 찾았기 때문에 여기에 투고하겠습니다.누군가의 고통을 덜어주길 바란다.

@deowk 이 문제에는 두 가지 부분이 있습니다.첫 번째는 componentWillReceiveProps()가 상태 변화에 대응하는 이상적인 방법이 아니라는 것입니다.주로 Redux에서처럼 반응적으로 생각하지 않고 명령적으로 생각하도록 하기 때문입니다.해결책은 현재 라우터 정보(위치, 매개 변수, 쿼리)를 스토어에 저장하는 것입니다.그러면 모든 상태가 동일한 위치에 있고 나머지 데이터와 동일한 Redux API를 사용하여 가입할 수 있습니다.

이 방법은 라우터의 위치가 변경될 때마다 실행되는 액션유형을 작성하는 것입니다.이는 리액트 라우터의 다음 1.0 버전에서는 간단합니다.

// routeLocationDidUpdate() is an action creator
// Only call it from here, nowhere else
BrowserHistory.listen(location => dispatch(routeLocationDidUpdate(location)));

이것으로 스토어 상태는 항상 라우터 상태와 동기화됩니다.그러면 위의 컴포넌트에서 쿼리 파라미터 변경 및 setState()에 수동으로 응답해야 하는 필요성이 해결됩니다.Redux의 Connector를 사용하면 됩니다.

<Connector select={state => ({ filter: getFilters(store.router.params) })} />

이 문제의 두 번째 부분은 뷰 레이어 외부에서 Redx 상태 변경에 대응하는 방법(루트 변경에 대한 응답으로 액션을 실행하는 방법 등)이 필요하다는 것입니다.필요에 따라 componentWillReceiveProps를 사용자가 설명한 것과 같은 단순한 케이스에 계속 사용할 수 있습니다.

단, 복잡한 경우에는 RxJ를 사용할 것을 권장합니다.이것이 바로 관측 가능한 설계, 즉 사후 대응적인 데이터 흐름입니다.

Redx에서 이를 수행하려면 먼저 관측 가능한 저장 상태 시퀀스를 만듭니다.rx의 observableFromStore()를 사용하여 이를 수행할 수 있습니다.

CNP가 제안하는 대로 편집

import { Observable } from 'rx'

function observableFromStore(store) {
  return Observable.create(observer =>
    store.subscribe(() => observer.onNext(store.getState()))
  )
}

그리고 관찰 가능한 연산자를 사용하여 특정 상태 변화에 가입하는 것이 중요합니다.로그인 성공 후 로그인 페이지에서 리다이렉트 하는 예를 다음에 나타냅니다.

const didLogin$ = state$
  .distinctUntilChanged(state => !state.loggedIn && state.router.path === '/login')
  .filter(state => state.loggedIn && state.router.path === '/login');

didLogin$.subscribe({
   router.transitionTo('/success');
});

이 실장은 componentDidReceiveProps()와 같은 필수 패턴을 사용하는 동일한 기능보다 훨씬 단순합니다.

앞서 설명한 바와 같이 이 솔루션은 다음 두 부분으로 구성됩니다.

1) 라우팅 정보를 상태에 링크합니다.

그러기 위해서는 react-router-redux를 설정하기만 하면 됩니다.지시대로 하면 괜찮을 거예요.

것이 되면, 「」를 할 수 .routing하다

주

2) 라우팅의 변경을 관찰하여 액션을 개시한다.

코드 어딘가에 다음과 같은 것이 있습니다.

// find this piece of code
export default function configureStore(initialState) {
    // the logic for configuring your store goes here
    let store = createStore(...);
    // we need to bind the observer to the store <<here>>
}

하고 싶은 것은 이고, 여러분은 의 변화를 관찰할 수 있습니다. 그러면 당신은dispatch이치

@설명한 바와 같이 @deowk를 사용할 수 .rx또는 독자적인 옵서버를 작성할 수 있습니다.

redexStoreObserver.js

var currentValue;
/**
 * Observes changes in the Redux store and calls onChange when the state changes
 * @param store The Redux store
 * @param selector A function that should return what you are observing. Example: (state) => state.routing.locationBeforeTransitions;
 * @param onChange A function called when the observable state changed. Params are store, previousValue and currentValue
 */
export default function observe(store, selector, onChange) {
    if (!store) throw Error('\'store\' should be truthy');
    if (!selector) throw Error('\'selector\' should be truthy');
    store.subscribe(() => {
        let previousValue = currentValue;
        try {
            currentValue = selector(store.getState());
        }
        catch(ex) {
            // the selector could not get the value. Maybe because of a null reference. Let's assume undefined
            currentValue = undefined;
        }
        if (previousValue !== currentValue) {
            onChange(store, previousValue, currentValue);
        }
    });
}

이제 '아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.reduxStoreObserver.js우리는 단지 변화를 관찰하기 위해 글을 썼다.

import observe from './reduxStoreObserver.js';

export default function configureStore(initialState) {
    // the logic for configuring your store goes here
    let store = createStore(...);

    observe(store,
        //if THIS changes, we the CALLBACK will be called
        state => state.routing.locationBeforeTransitions.search, 
        (store, previousValue, currentValue) => console.log('Some property changed from ', previousValue, 'to', currentValue)
    );
}

위의 코드는 전환 전 location을 호출할 때마다 당사의 함수를 호출하도록 합니다.상태 변경을 검색합니다(사용자가 탐색한 결과).필요에 따라 쿼리 문자열 등을 관찰할 수 있습니다.

변경의 , 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」 「 」만 있으면 됩니다.store.dispatch(yourAction)핸들러 내부에 있습니다.

언급URL : https://stackoverflow.com/questions/31268740/firing-redux-actions-in-response-to-route-transitions-in-react-router