2017-01-13 3 views
0

클라이언트를 만드는 데 필요한 redux 응용 프로그램을 설정하고 있습니다. 초기화 후에 클라이언트에는 특정 작업에 따라 호출해야하는 리스너 및 API가 있습니다.redux에 클라이언트를 저장하는 방법은 무엇입니까?

그 때문에 클라이언트 인스턴스를 유지해야합니다. 지금, 나는 그것을 국가에 저장하고있다. 그게 맞습니까?

그래서 나는 다음과 같은 redux 액션 크리에이터를 가지고 있지만 메시지를 보내려 할 때 client.say (...) API를 호출해야합니다.

그러나 클라이언트 개체는 어디에서 가져와야합니까? 상태에서 클라이언트 개체를 검색해야합니까? 내 이해는 그게 희박한 반 패턴이다. redux로 이것을하는 적절한 방법은 무엇입니까?

낯선 사람 - 실제로 상태를 변경하지 않을 때 메시지 작성자가 작업 작성자로 간주되어야합니까?

액션 : 액션 제작자로 클라이언트 객체를 주입

// reducer.js 
import { CLIENT_MESSAGE_RECEIVED, CLIENT_INITIALIZE } from '../actions/client'; 
import irc from 'irc'; 

export default function client(state: Object = { client: null, channels: {} }, action: Object) { 
    switch (action.type) { 
    case CLIENT_MESSAGE_RECEIVED: 
     return { 
     ...state, 
     channels: { 
      ...state.channels, 
      [action.to]: [ 
      // an array of messages 
      ...state.channels[action.to], 
      // append new message 
      { 
       to: action.to, 
       from: action.from, 
       body: action.body, 
      } 
      ] 
     } 
     }; 

    case CLIENT_JOIN_CHANNEL: 
     return { 
     ...state, 
     channels: { 
      ...state.channels, 
      [action.channel]: [], 
     } 
     }; 

    case CLIENT_INITIALIZE: 
     return { 
     ...state, 
     client: action.client, 
     }; 
    default: 
     return state; 
    } 
} 

답변

1

사용 미들웨어 : 여기

// actions.js 

import irc from 'irc'; 

export const CLIENT_INITIALIZE = 'CLIENT_INITIALIZE'; 
export const CLIENT_MESSAGE_RECEIVED = 'CLIENT_MESSAGE_RECEIVED'; 
export const CLIENT_MESSAGE_SEND = 'CLIENT_MESSAGE_SEND'; 

export function messageReceived(from, to, body) { 
    return { 
    type: CLIENT_MESSAGE_RECEIVED, 
    from: from, 
    to: to, 
    body: body, 
    }; 
}; 

export function clientSendMessage(to, body) { 
    client.say(...); // <--- where to get client from? 
    return { 
    type: CLIENT_MESSAGE_SEND, 
    to: to, 
    body: body, 
    }; 
}; 

export function clientInitialize() { 
    return (dispatch) => { 
    const client = new irc.Client('chat.freenode.net', 'react'); 

    dispatch({ 
     type: CLIENT_INITIALIZE, 
     client: client, 
    }); 

    client.addListener('message', (from, to, body) => { 
     console.log(body); 
     dispatch(messageReceived(from, to, body)); 
    }); 
    }; 
}; 

그리고는 감속기입니다! :)

export default function clientMiddleware(client) { 
    return ({ dispatch, getState }) => { 
    return next => (action) => { 
     if (typeof action === 'function') { 
     return action(dispatch, getState); 
     } 

     const { promise, ...rest } = action; 
     if (!promise) { 
     return next(action); 
     } 

     next({ ...rest }); 

     const actionPromise = promise(client); 
     actionPromise.then(
     result => next({ ...rest, result }), 
     error => next({ ...rest, error }), 
    ).catch((error) => { 
     console.error('MIDDLEWARE ERROR:', error); 
     next({ ...rest, error }); 
     }); 

     return actionPromise; 
    }; 
    }; 
} 

은 다음에 적용 :

const client = new MyClient(); 

const store = createStore(
    combineReducers({ 
    ... 
    }), 
    applyMiddleware(clientMiddleware(client)) 
); 

가 그런 행동 제작자에서 사용할 수 있습니다 :

export function actionCreator() { 
    return { 
    promise: client => { 
     return client.doSomethingPromisey(); 
    } 
    }; 
} 

이는 대부분 react-redux-universal-hot-example boilerplate project에서 적응된다. this abstraction in action creators을 만드는 데 사용되는 시작, 성공 및 실패 작업을 정의 할 수있는 추상화를 제거했습니다.

클라이언트가 비동기 적이 지 않은 경우 redux-thunk가 dispatch으로 전달하는 방식과 유사하게이 코드를 클라이언트에 전달하기 만하면됩니다.