Javascript 在React/Redux中未触发操作
我是redux新手,尝试从后端API获取内容。由于某种原因,我调用的操作没有到达减速机,甚至没有执行。我最初认为这是因为它无法访问存储,因为它有一个父组件,但我的提供程序配置良好,并且在同一级别上还有另一个组件,就在我开始认为这是我的调度问题之后,但老实说,我不知道。我已附上代码,我觉得是相关的,任何贡献将不胜感激 actions/viewers.js reducers/viewers.js reducer/index.js App.js store.js 您已将ExtractConcurrentViewer映射到connect中的道具,但未将其添加到已分解的道具对象。因为它们共享同一个名称,这意味着你正在调用你的动作创建者,而它没有被绑定到分派,所以它不会被传递到你的还原者 常量仪表板={ 当前客户端, 提取图表数据, 身份验证:{user}, 配置文件:{profile,loading}, 图表:{cdn,p2p,maxSum,maxCdn}, 查看器:{concurrence}, ExtractConcurrentViewer//{Javascript 在React/Redux中未触发操作,javascript,reactjs,redux,Javascript,Reactjs,Redux,我是redux新手,尝试从后端API获取内容。由于某种原因,我调用的操作没有到达减速机,甚至没有执行。我最初认为这是因为它无法访问存储,因为它有一个父组件,但我的提供程序配置良好,并且在同一级别上还有另一个组件,就在我开始认为这是我的调度问题之后,但老实说,我不知道。我已附上代码,我觉得是相关的,任何贡献将不胜感激 actions/viewers.js reducers/viewers.js reducer/index.js App.js store.js 您已将ExtractConcurren
就我个人而言,我不分解我的道具,这是一个原因。我更喜欢代码明确说明道具的值和函数来自哪里。ExtractConcurrentViewer。但这是我的偏好。我看到你在使用钩子。为什么不使用像useDispatch、useSelector这样的钩子?尝试使用useDispatch钩子触发动作。然后是loadUser操作吗?我没有看到它
import axios from 'axios';
import { VIEWERS_LOADED, VIEWERS_ERROR } from './types';
export const loadData = async (body, http) => {
const config = {
headers: {
'Content-Type': 'application/json',
},
};
try {
const res = await axios.post(
http,
body,
config
);
return res.data;
} catch (error) {
console.log(error);
}
};
export const extractConcurrentViewers = (from, to, aggregate) => async dispatch => {
console.log("CONCURRENT VIEWERS");
const body = {
session_token: localStorage.token,
from,
to,
};
try {
let aggregateConcur = null;
const graphConccur = await loadData(body, 'http://localhost:5000/audience');
console.log('extractViews -> res_1', graphConccur);
if (aggregate !== null) {
body.aggregate = aggregate
aggregateConcur = await loadData(body, 'http://localhost:5000/audience');
}
console.log('extractaggregateViewers -> res_2', aggregateConcur);
dispatch({
type: VIEWERS_LOADED,
payload: {
graphConccur,
aggregateConcur
},
});
} catch (error) {
console.log(error);
dispatch({
type: VIEWERS_ERROR,
});
}
}
import {
VIEWERS_LOADED,
VIEWERS_ERROR,
} from '../actions/types';
const initialState = {
session_token: localStorage.getItem('token'),
concurrence: null,
aggConcurrence: null,
};
export default function (state = initialState, action) {
const { type, payload } = action;
switch (type) {
case VIEWERS_LOADED:
return {
...state,
...payload,
concurrence: payload.graphConccur.audience,
aggConcurrence: payload.aggregateConcur.audience,
};
case VIEWERS_ERROR:
return {
...state,
concurrence: null,
aggConcurrence: null,
};
default:
return state;
}
}
import {combineReducers} from 'redux';
import alert from './alert';
import auth from './auth'
import profile from './profile'
import chart from './chart'
import viewers from './viewers'
export default combineReducers({
alert,
auth,
profile,
chart,
viewers
});
import React, { useEffect } from 'react';
import Navbar from './components/layout/Navbar';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Landing from './components/layout/Landing';
import Login from './components/auth/Login';
import Register from './components/auth/Register';
import Alert from './components/layout/Alert';
import Dashboard from './components/dashboard/Dashboard';
import PrivateRoute from './components/routing/PrivateRouting';
import { Provider } from 'react-redux';
import store from './store';
import { loadUser } from './actions/auth';
import setAuthToken from './utils/setAuthToken'
import './App.css';
if (localStorage.token) {
setAuthToken(localStorage.token);
}
const App = () => {
useEffect(() => {
store.dispatch(loadUser())
}, []);
return (
<Provider store={store}>
<Router>
<Navbar />
<Route exact path='/' component={Landing} />
<section className='container'>
<Alert />
<Switch>
<Route exact path='/login' component={Login} />
<Route exact path='/register' component={Register} />
<PrivateRoute exact path='/dashboard' component={Dashboard} />
</Switch>
</section>
</Router>
</Provider>
);
};
export default App;
import React, { useEffect, Fragment } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Spinner from '../layout/Spinner';
import BandWidth from './BandWidth';
import Concurrent from './Concurrent';
import { extractCurrentClient } from '../../actions/profile';
import { extractchartData } from '../../actions/chart';
import { extractConcurrentViewers } from '../../actions/viewers';
const Dashboard = ({
extractCurrentClient,
extractchartData,
auth: { user },
profile: { profile, loading },
chart: { cdn, p2p, maxSum, maxCdn },
viewers: {concurrence}
}) => {
useEffect(() => {
extractCurrentClient();
extractchartData('max', 1585834831000, 1589118031000);
extractConcurrentViewers(1585834831000, 1589118031000);
}, []);
return loading && profile === null ? (
<Spinner />
) : (
<Fragment>
<h1 className='large text-primary'>Streaming</h1>
<p className='lead'>
<i className='fas fa-chart-line'></i>
Welcome {user && user.lname}
</p>
<BandWidth cdn={cdn} p2p={p2p} maxSum={maxSum} maxCdn={maxCdn} />
{/* <Concurrent concurrence={concurrence}/> */}
</Fragment>
);
};
Dashboard.propTypes = {
extractCurrentClient: PropTypes.func.isRequired,
extractchartData: PropTypes.func.isRequired,
extractConcurrentViewers: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
profile: PropTypes.object.isRequired,
};
const mapStateToProps = (state) => ({
auth: state.auth,
profile: state.profile,
chart: state.chart,
viewers: state.viewers,
});
export default connect(mapStateToProps, {
extractCurrentClient,
extractchartData,
extractConcurrentViewers
})(Dashboard);
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
export default store;