Мой проект состоит из бэкэнда (nodejs, express, mysql) и внешнего интерфейса (reactjs, redux).
Поток визуализированного компонента находится в простом редукте pattern-
- in
ComponentDidMount
Я вызываю создателя действия this.props.getResource()
- в создателе действия. Я использую ax ios, чтобы вызвать бэкэнд и отправить действие в обратном вызове следующим образом. :
действия. js
export const getResource = () => dispatch => {
axios.get(API_URL/path/to/resource)
.then(res => {
dispatch({
type: SOME_RESOURCE,
payload: res.data
});
})
.catch(e =>
dispatch({
type: ERROR,
payload: e
})
);
};
в редукторе отправляю обратно компоненту состояние с новым массивом:
редукторы. js
export default function(state = initialState, action) {
switch (action.type) {
case SOME_RESOURCE:
return {
...state,
resources: [...state.resources, action.payload] // add new resource to existing array
};
}
default: return state;
}
}
Работает как в нем должны использоваться API REST, но теперь я должен sh заменить определенный вызов API сокетом, чтобы данные отображались в режиме реального времени без необходимости обновлять sh страницу.
Как преобразовать Приведенный выше пример использования сокетов вместо вызовов API?
Это то, что я пробовал:
- Поток запускается так же - я вызываю создателя действия в
ComponentDidMount
- Я изменил создателя действий на следующее:
действий. js
import io from 'socket.io-client';
const socket = io(); // localhost backend
export const getResource= () => dispatch => {
socket
.on("getResourceEvent", res => {
dispatch({
type: SOME_RESOURCE,
payload: res.data
});
})
.on("onError", e => {
dispatch({
type: ERROR,
payload: e
});
});
};
без изменений в
редукторах. js Это работает, но при каждом рендеринге компонента store.getState()
вызывается 1 дополнительное время. При первом рендеринге getState()
вызывается 1 раз, и если я обновлю sh страницу, я получаю 2 вызова от getState()
и т. Д.
Что вызывает такое поведение и как его предотвратить?
Редактировать:
магазин. js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const initialState = {};
const middleware = [ thunk ];
var createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
var store = createStoreWithMiddleware(
rootReducer,
initialState,
applyMiddleware(...middleware)
)
store.subscribe(() => console.log("Store.getState()", store.getState()))
export default store;