Я получаю данные, но проблема в том, что я могу получить к ним доступ только внутри одного и того же файла api.js
. Как я могу сказать, это не возвращает никакого значения. Я сделал много вариаций этого фрагмента кода. Он либо возвращает initial state
, либо undefined
. Интересно то, что если есть error
, это заполнит объект error
. Извините за столько кода, но кто-то может помочь мне успешно реализовать socket.io
с React/ Redux.
Вот что я получил до сих пор:
api.js
Здесь я успешно подключаюсь к API, получаю данные, но не могу использовать их вне этого файла. Если вернуть объект, это будет undefined
, но если я console.log
это или даже return
console.log и использую файл в другом компоненте / файле, данные будут отображаться в моей консоли, но только это Кстати, и только в моей консоли ... не могу отправить данные и повторно использовать их во всем приложении, которое я пытаюсь создать.
import axios from 'axios';
import io from "socket.io-client";
export function fetchData() {
const configUrl = 'API endpoint';
axios.get(configUrl).then(res => {
const socketUrl = res.data.config.liveDistributionSSL;
const socket = io(socketUrl);
socket.on('connect', function () {
socket.emit('subscribe', {
subscribeMode: 'topSportBets',
language: {
default: 'en'
},
deliveryPlatform: 'WebSubscribe',
playerUuid: null,
subscribeOptions: {
autoSubscribe: true,
betCount: 3,
excludeMeta: false,
resubscriptions: 0,
fullBetMeta: true,
browser: {}
}
});
let relevantData = {}; // Object that I'm trying to assign values to and return
socket.on('message', async (message) => {
switch (message.type) {
case 'state': // We have all the data needed to show
relevantData = await Object.values(Object.values(message.data)[9]);
break;
case 'currentMatches':
// We have matches to update
console.log('Matches =>', message.contentEncoding);
break;
case 'betchange':
// We have match bets to update
console.log('Match bets =>', message.contentEncoding);
break;
default: break;
}
return relevantData;
});
socket.on("disconnect", () => console.log("Client disconnected"));
});
});
}
действия / index.js
Это мой главный создатель действий. Код, который вы видите, был моей последней попыткой опробовать новый подход, все тот же результат.
import { GET_DATA, GET_ERROR } from './types';
import { fetchData } from '../api'
export const getDataAsync = () => async dispatch => {
try {
const response = await fetchData();
dispatch({ type: GET_DATA, payload: response });
} catch (e) {
dispatch({ type: GET_ERROR, payload: 'Something went wrong ', e });
}
};
редукторы / data_reducer.js
Здесь я делаю простой редуктор и в зависимости от payload
меняю initial state
import { GET_DATA, GET_ERROR } from '../actions/types';
const INITIAL_STATE = {
apiData: {},
errorMessage: {}
};
const dataReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case GET_DATA:
return { ...state, apiData: action.payload };
case GET_ERROR:
return { ...state, errorMessage: action.payload };
default:
return state;
}
}
export default dataReducer;
редукторы / root_reducer.js
Здесь я комбинирую редукторы, а затем внедряю мою root_reducer
в мою store
конфигурацию
import { combineReducers } from 'redux';
import dataReducer from './data_reducer';
const rootReducer = combineReducers({
allData: dataReducer
});
export default rootReducer;
PrimaryLayoutContainer.js
* Это будет мой основной layout
контейнер, в котором я реализую маршрутизацию, отображаю компонент PrimaryLayout
и где ** я пытаюсь передать значения реквизита *
import React, { Component } from 'react';
import {connect} from 'react-redux';
import PrimaryLayout from "../components/PrimaryLayout";
import { withRouter } from 'react-router'
import * as myData from '../actions';
class PrimaryLayoutContainerComponent extends Component {
render() {
return (
<div>
<PrimaryLayout history={this.props.history}
allData={this.props.allData}
/>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
allData: state.allData
}
}
export default withRouter(connect(mapStateToProps, myData)(PrimaryLayoutContainerComponent));
PrimaryLayout.js
Там, где я пытаюсь реализовать данные, всю маршрутизацию и отображение основных компонентов и т. Д., Но здесь я остановился, потому что не получаю необходимые данные
import React, {Component} from 'react';
import {Switch, Route, Redirect, Link} from 'react-router-dom';
import Favorites from './Favorites';
... a lot of other imports of my components
class PrimaryLayout extends Component {
constructor(props) {
super(props);
this.state = {
currentRoute: '',
// data: {}
}
}
componentWillReceiveProps(nextProps) {
this.setState({
currentRoute: nextProps.history.location.pathname
})
}
componentWillMount() {
this.setState({
currentRoute: this.props.history.location.pathname
})
}
componentDidMount() {
console.log(this.props); // Where i'm trying to get access to the data
}
render() {
const {currentRoute} = this.state;
return (
<div className='main-nav'>
<nav className="topnav">
<ul>
<li className={currentRoute === "/favorites" ? "active" : ""}>
<Link to="/favorites"><div className='star'></div> Favorites </Link> </li>
<li className={currentRoute === "/football" ? "active" : ""}>
<Link to="/football"><div className='football'></div> Football </Link> </li>
<li className={currentRoute === "/basketball" ? "active" : ""}>
<Link to="/basketball"><div className='basketball'></div> Basketball </Link> </li>
<li className={currentRoute === "/tennis" ? "active" : ""}>
<Link to="/tennis"><div className='tennis'></div> Tennis </Link> </li>
<li className={currentRoute === "/baseball" ? "active" : ""}>
<Link to="/baseball"><div className='baseball'></div> Baseball </Link> </li>
<li className={currentRoute === "/waterpolo" ? "active" : ""}>
<Link to="/waterpolo"><div className='waterpolo'></div> Waterpolo </Link> </li>
</ul>
</nav>
<main>
<Switch>
<Route path='/favorites' component={Favorites} />
<Route path='/football' component={Football} />
<Route path='/basketball' component={Basketball} />
<Route path='/tennis' component={Tennis} />
<Route path='/baseball' component={Baseball} />
<Route path='/waterpolo' component={Waterpolo} />
<Route path='/volleyball' component={Volleyball} />
<Route path='/handball' component={Handball} />
<Route path='/formula1' component={Formula} />
<Redirect to="/football"/>
</Switch>
</main>
</div>
)
}
}
export default PrimaryLayout;
index.js
Это будет мой основной index.js
файл, в котором я настраиваю элементы хранилища и рендеринга для DOM
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import './assets/styles/App.css';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './reducers/root_reducer';
import thunk from 'redux-thunk';
function configureStore() {
return createStore(
rootReducer,
applyMiddleware(thunk)
);
}
const myStore = configureStore();
ReactDOM.render(
<Provider store={myStore}>
<App />
</Provider>,
document.getElementById('root')
)
Примечание:
Как я уже говорил, я успешно подключаюсь к конечной точке API, получая необходимые данные, но я могу манипулировать ими только внутри одного и того же файла api.js
. Я гуглю весь день, но не нашел ничего подходящего для моей проблемы. Есть много примеров с PHP, Java, но не так много с React, Redux и т. Д. Я никогда раньше не использовал Socket.io
, поэтому, пожалуйста, мои дорогие друзья, помогите мне ...: /
Главный вопрос здесь:
Как я могу успешно реализовать Scoket.io и использовать Redux для отправки данных API, выбрасывая все мои основные компоненты React, вместо того, чтобы делать это очень DRY , то есть реализовывать одну и ту же логику в каждом компоненте и каждый раз получить все данные, а не только соответствующие.
Если я могу сделать это в одном месте (вне файла api.js
), я могу сделать это везде, и этот ответ более чем признателен и будет принят немедленно.