2017-12-23 1 views
0

조치가 해당 구성 요소에 매핑 된 감속기로 전달되면 내 반응 구성 요소에서 내 props 속성을 업데이트하는 데 문제가 있습니다. 나는 코드를 보여주는 길을 따라 설명 할 것이다.Redux 감속기가 React 구성 요소의 Prop 값을 외부로 디스패치하지 않음 React 구성 요소에서

우선 먼저, 반응 구성 요소 (전자 메뉴 항목 클릭에서 시작된 디스패치) 외부로 작업을 발송하려고합니다.

조치를 디스패치하는 메뉴 서비스 기능입니다. 코드가 범위 밖이기 때문에 돌아 오는 저장소의 인스턴스를 얻는 StoreProvider이이 완료되고

dispatchMessage(): void { 
    let message = messageService.getMessage(); 
    let store = StoreProvider.getInstance().store; 
    store.dispatch(loadMessage(message)); 
} 

공지 사항 : 우리는 발송 후 console.log(store.getState()) 작업을 수행하는 경우에, 우리는 제대로 가게의 상태에서 메시지를 볼 것이다

import { createStore } from 'redux'; 

import allReducers from '../reducers/index'; 

export default class StoreProvider { 
    private static _instance: StoreProvider; 
    store: any = null; 

    constructor() { 
     this.store = createStore(
      allReducers 
     ); 
    } 

    public static getInstance(): StoreProvider { 
     return StoreProvider._instance || (StoreProvider._instance = new StoreProvider()); 
    } 
} 

이 내가 응용 프로그램 구성 요소를 부트 스트랩과 같은 저장소 공급자를 사용하여 저장소를로드 내 index.tsx 파일입니다 (이것은 새로운 인스턴스를 채 웁니다 다음 반작용 구성 요소로, 이것은 StoreProvider.ts입니다 생성자가 나중에 메뉴 항목에서 액세스 할 수있는 저장소를 설정하는 StoreProvider) :

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux'; 

import allReducers from './reducers/index'; 
import App from './app'; 
import StoreProvider from './providers/store-provider'; 

const bootstrapperElement: HTMLElement = document.getElementById('app') as HTMLElement; 

const store = StoreProvider.getInstance().store; 

ReactDOM.render(
    <Provider store={store}> 
     <App /> 
    </Provider>, 
    bootstrapperElement); 

좋아요. 이것은 작업이 발송되는 지점까지 연결되는 방식입니다. 나는 메뉴 서비스 기능에 내 행동을 파견 할 때 그래서,이 작업을 호출 : 작업이이 감속기에 의해 포착되어 전달되는

export const loadMessage = (message: any) => { 
    return { 
     type: 'MESSAGE_LOADED', 
     payload: message 
    }; 
}; 

되면. console.log(action.payload)에 주목하자.이 시점에서 메뉴 서비스에서 올바르게 전달 된 메시지를 기록하고 예상되는 내용을 볼 수있다.

export default (state: any = null, action: any) => { 
    switch (action.type) { 
    case 'MESSAGE_LOADED': 
     console.log(action.payload); 
     return action.payload; 
    default: 
     return state; 
    } 
}; 

소품에 그 상태를 매핑하는 구성 요소입니다 : 내가 텍스트 'TEST'와 H2 요소를 클릭 그래서

import React, { Component } from 'react'; 
import ReactDOM from 'react-dom'; 
import { bindActionCreators } from 'redux'; 
import { connect } from 'react-redux'; 

class SideMenu extends Component<any> { 
    render() { 
     return (
      <div> 
       <h2 onClick={() => console.log(this.props.fileExplorer)}>Test</h2> 
      </div> 
     ); 
    } 
} 

const mapStateToProps = (state: any) => { 
    return { 
     fileExplorer: state.fileExplorer 
    }; 
}; 

export default connect<any>(mapStateToProps, {})(SideMenu); 

, 난 항상 널 얻고 기본이되는 그 메시지를받는 감속기에 원래 전달 된 값 (감속기의 console.log가 실제로 메뉴 서비스에서 작업이 전달 될 때 올바른 값을 인쇄하고 있음에도 불구하고). 이 문제의 모든 지원이 크게 감사합니다

import { combineReducers } from 'redux'; 

import FileExplorerReducer from './file-explorer'; 

const allReducers = combineReducers({ 
    fileExplorer: FileExplorerReducer 
}); 

export default allReducers; 

:

은 또한이 내가 가게에 추가하고 내 감속기입니다. 나는이 순간에 StoreProvider와 관련된 이슈에 관심이 있고 매장의 2 개의 개별 인스턴스가있을 가능성이 있다고 생각합니다. 감속기가 action.payload를 반환하고 매장의 fileExplorer 상태가 (적어도 디스패치 후 메뉴 서비스를 체크인하여) 업데이트 되더라도 this.props.fileExplorer 구성 요소가 항상 null 인 이유를 확실히 알 수 없습니다.

변경이 허용 대답에 따라 위의 질문에 대답 :

그래서 IPC (프로세스 간 통신)를 허용하는 데, 우리는 BrowserWindow.webContents에서 메시지를 게시했다.과 같이 메뉴 서비스() 보내

let message = let message = messageService.getMessage(); 
BrowserWindow.getFocusedWindow().webContents.send('dispatch-action', { payload: { message}); 

그리고 다음 저장소 공급자에, 내가 그렇게 그 가게의 인스턴스가 렌더링 과정에서 주요 과정에서 게시 메시지를 수신 할 수있는 생성자의 가입자를 추가를 과 같이 :

import { ipcRenderer } from 'electron'; 

export default class StoreProvider { 
    private static _instance: StoreProvider; 
    store: any = null; 

    constructor() { 
     this.store = createStore(
      allReducers 
     ); 

     ipcRenderer.on('dispatch-action', (event: any, arg: any) => { 
      this.store.dispatch(loadMessage(arg.payload)); 
     }); 
    } 

    public static getInstance(): StoreProvider { 
     return StoreProvider._instance || (StoreProvider._instance = new StoreProvider()); 
    } 
} 
+1

Sidemenu 구성 요소 mapstatetoprops에서 상태를 로깅하는 콘솔을 사용하여 올바른 상태임을 확인하십시오. – cdoshi

+0

@cdoshi가 바로 그 역할을 수행했습니다. 그것은 나에게 속성 "fileExplorer : null"을 가진 객체를 제공합니다. 확실히 재밌는 무언가가 가게에서 계속되고있는 것 같아요 – Shawn

+0

스토어가 프로 바이더에로드 될 때 스토어가 임의의 숫자로 생성 될 때 fileExplorer에 대한 기본값이 추가되었습니다. 52를 얻었을 때 메뉴 서비스에있는 상점의 인스턴스입니다. 75 점이 있습니다. 따라서 상점의 인스턴스가 두 개인 경우 하나만 유지하는 방법을 찾아야합니다. 내가 사용하는 싱글 톤을 구현하고 있다고 생각했다. – Shawn

답변

1

나는 완전히 특정하지만 전자의 메뉴 이벤트를 실행하기 위해 노력하고 말하는 당신의 설명을 기반으로하지, 난 당신이 메뉴 이벤트를 전달하고 처리하는 확인하는 것이 좋습니다 싶습니다 수 있습니다. 반응 구성 요소를 호스팅하는 렌더러 프로세스가 아닌 경우 서로 다른 각 프로세스가 격리 된 저장소 상태를 보일 수 있습니다. 또는 저장소 동기화 미들웨어가 필요하거나 렌더러 프로세스로 IPC를 호출 한 다음 렌더러에서 렌더러가 직접 redux 저장소에 작업을 전달하도록 할 수 있습니다.

관련 문제