我一直在尝试使用redux和redux-saga创建一个React应用,但是我一直无法使它工作,因此我总是得到undefined
的值。
这是我的组件catalogs/index.js
:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import CatalogHeader from './CatalogHeader';
import CircularProgress from '@material-ui/core/CircularProgress';
import {getCatalogs} from 'actions/Catalogs';
import IntlMessages from 'util/IntlMessages';
import CustomScrollbars from 'util/CustomScrollbars';
class Catalogs extends Component {
constructor() {
super();
this.state = {
anchorEl: null
}
}
updateSearch = (evt) => {
this.props.updateSearch(evt.target.value);
this.onSearchTodo(evt.target.value)
};
render() {
const {catalogsList} = this.props;
return (
<div className="app-wrapper">
<div className="animated slideInUpTiny animation-duration-3">
<div className="app-module">
<div className="module-box">
<div className="module-box-header">
<CatalogHeader catalogsList={catalogsList}
placeholder="Buscar" user={this.props.user}
onChange={this.updateSearch.bind(this)}
value={this.props.searchTodo}/>
</div>
</div>
</div>
</div>
</div>
)
}
}
const mapStateToProps = ({catalogs, settings}) => {
const {width} = settings;
const {catalogsList} = catalogs;
return {
width,
catalogsList,
}
};
export default connect(mapStateToProps, {
getCatalogs,
})(Catalogs);
这是另一个组件catalogs/CatalogHeader.js
import React from 'react';
import IconButton from '@material-ui/core/IconButton';
import Button from '@material-ui/core/Button';
import {Dropdown, DropdownMenu, DropdownToggle, Popover} from 'reactstrap';
import SearchBox from 'components/SearchBox';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import FormHelperText from '@material-ui/core/FormHelperText';
import Select from '@material-ui/core/Select';
class CatalogHeader extends React.Component {
handleChange = name => event => {
this.setState({[name]: event.target.value});
};
onSearchBoxSelect = () => {
this.setState({
searchBox: !this.state.searchBox
})
};
constructor() {
super();
this.state = {
anchorEl: undefined,
searchBox: false,
popoverOpen: false
};
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({
popoverOpen: !this.state.popoverOpen
});
}
printCatalogs(catalogs) {
console.log(catalogs);
}
render() {
const {catalogs} = this.props;
return (
<div className="module-box-header-inner catalogs-header">
<div className="col-5 catalogs-header">
<FormControl className="w-100 mb-2">
{this.printCatalogs(this.props.catalogs)}
<InputLabel htmlFor="age-simple">Seleccione Catálogo</InputLabel>
<Select
value={this.state.age}
onChange={this.handleChange('age')}
input={<Input id="ageSimple1"/>}>
{catalogs.map(catalog =>
<MenuItem key={catalog}>
{catalog}
</MenuItem>,
)}
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</div>
<div className="module-box-header-right col-7 catalogs-header">
<div className="search-bar right-side-icon bg-transparent d-none d-sm-block col-6">
<div className="form-group">
<input className="form-control border-0" type="search" placeholder="Buscar"/>
<button className="search-icon"><i className="zmdi zmdi-search zmdi-hc-lg"/></button>
</div>
</div>
<div className="col-6">
<div className="catalogs-header catalogs-header-buttons">
<Button variant="contained" className="jr-btn bg-white">
<i className="zmdi zmdi-filter-list zmdi-hc-fw"/>
<span>Filtrar</span>
</Button>
<Button variant="contained" className="jr-btn bg-white">
<i className="zmdi zmdi-sort zmdi-hc-fw"/>
<span>Ordenar</span>
</Button>
</div>
</div>
</div>
</div>
)
}
}
export default CatalogHeader;
这是我的操作文件:
import {
GET_CATALOGS,
GET_CATALOGS_SUCCESS,
SHOW_MESSAGE
} from 'constants/ActionTypes';
export const getCatalogs = (group) => {
return {
type: GET_CATALOGS,
payload: group
};
};
export const getCatalogsSuccess = (catalogs) => {
return {
type: GET_CATALOGS_SUCCESS,
payload: catalogs
}
};
export const showCatalogsMessage = (message) => {
return {
type: SHOW_MESSAGE,
payload: message
};
};
这是我的减速器文件:
import {
GET_CATALOGS,
SHOW_MESSAGE,
HIDE_MESSAGE,
GET_CATALOGS_SUCCESS
} from 'constants/ActionTypes';
const INIT_STATE = {
loader: false,
alertMessage: '',
showMessage: false,
catalogsList: null
};
export default (state=INIT_STATE, action) => {
switch (action.type) {
case GET_CATALOGS_SUCCESS: {
return {
...state,
loader: false,
catalogsList: action.payload
}
}
case SHOW_MESSAGE: {
return {
...state,
alertMessage: action.payload,
showMessage: true,
loader: false
}
}
case HIDE_MESSAGE: {
return {
...state,
alertMessage: '',
showMessage: false,
loader: false
}
}
default:
return state;
}
}
这是我的sagas文件:
import {all, call, fork, put, takeEvery} from "redux-saga/effects";
import {catalogs} from 'backend/Catalogs';
import {GET_CATALOGS} from "constants/ActionTypes";
import {getCatalogs, getCatalogsSuccess, showCatalogsMessage} from 'actions/Catalogs';
const getCatalogsRequest = async (group) => {
await catalogs.getCatalogs(group)
.then(catalogsList => catalogsList)
.catch(error => error);
}
function* getCatalogsListFromRequest({payload}) {
const {group} = payload;
try {
const catalogsList = yield call(getCatalogsRequest, group);
if (catalogsList.message) {
yield put(showCatalogsMessage(catalogsList.Message));
} else {
yield put(getCatalogsSuccess(catalogsList.catalogsList))
}
} catch (error) {
yield put(showCatalogsMessage(error));
}
}
export function* getCatalogsList() {
yield takeEvery(GET_CATALOGS, getCatalogsListFromRequest);
}
export default function* rootSaga() {
yield all([
fork(getCatalogsList)
]);
}
这是通过Axios执行ajax请求的文件(我确定永远不会到达此代码,也永远不会执行对后端服务器的请求):
import axios from 'axios';
import {backendServer} from './constants';
const getCatalogsEndpoint = backendServer + 'api/util/catalogs/';
const getCatalogs = (group) => {
console.log('here inside getCatalogs in backend/Catalogs');
return axios.get(getCatalogsEndpoint+(group=null)?null:'?group='+group)
.then(Response => {
return {catalogsList: Response.data}
})
.catch(Error => Error);
};
export const catalogs = {
getCatalogs: getCatalogs
}
在CatalogsHeader.js
中出现问题,因为this.props.catalogsList
的值始终为undefined
:
答案 0 :(得分:0)
我在 CatalogHeader 中看到了问题。我想,你指的是错误的流行音乐。
在 index.js 中,您将道具作为 catalogsList={catalogsList} 传递给 CatalogHeader。
但是在 CatalogHeader 中,您以 const {catalogs} = this.props; 的形式访问 prop,即未定义的目录。请尝试将其更改为 catalogsList。