我是React / Redux编码的初学者。我已经迷失在容器和组件的反应。在Redux之前,我可以轻松获取JSON数据。由于状态的复杂性,我决定学习Redux。时间不足使我不得不问这个问题。 我不明白为什么我的道具没有装满减速器。
(我正在尝试获取一个名为“事件”的json数组。)
这是我的代码:
./ actions / eventAction.js
import C from './actionType';
export function fetchEvents() {
return function (dispatch) {
dispatch(requestEvent());
return fetch('http://localhost:3000/json/data.json')
.then(handleErrors)
.then(
response => response.json(),
error => console.log('An error occurred.', error),
)
.then((json) => {
dispatch(receivedEvents(json));
},
);
};
}
export const requestEvent = () => ({
type: C.REQUEST_EVENT
});
export const receivedEvents = json => ({
type: C.RECEIVED_EVENTS,
payload: json.events
});
// Handle HTTP errors since fetch won't.
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
./ Component / Event.js
import React from 'react'
import PropTypes from 'prop-types'
export const Event = ({ title, description, category, tags, img, onClick}) => (
<div className="card eq-event-card mb-5">
<img className="img-speech-bubble card-img-top eq-event-img" src={img} alt="Card image cap"></img>
<div className="card-body shadow-lg">
<div className="container d-flex flex flex-column mb-5">
<div className="fab-button justify-content-center">
<i className="fas fa-plus my-3" />
</div>
<div className="eq-event-header container d-flex flex-row justify-content-between">
<div className="eq-event-title col-md-9">
<p className="card-title h3 text-right">
{title}
</p>
</div>
<div className="eq-event-cat text-center col-md-3" >
<p className="h5">{category})</p>
</div>
</div>
<div className="container">
<div className="row">
<div className="eq-event-desc col-md-8 col-sm-12">
<p className="text-justify card-text text-muted">
{description}
</p>
</div>
<div className="eq-event-tag col-md-4 col-sm-12 ">
<ul className="text-justify">
<li className="text-muted">{tags}</li>
</ul>
</div>
</div>
</div>
</div>
<div className="d-flex justify-content-center">
<button onClick={onClick} href="#" className="more-button btn btn-primary">اطلاعات بیشتر <i className="fas fa-arrow-left" /></button>
</div>
</div>
</div>
)
Event.propTypes = {
id: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
desc: PropTypes.string.isRequired,
category: PropTypes.string.isRequired,
tags: PropTypes.arrayOf(PropTypes.string),
onClick: PropTypes.func.isRequired,
img: PropTypes.string.isRequired
}
export default Event
./ Components / EventList.js
import React from 'react'
import PropTypes from 'prop-types'
import Event from './Event'
export const EventList = ({events}) => (
events.map((event, index) => (
<Event key={index} {...event} />
))
)
EventList.propTypes = {
events: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
title: PropTypes.string.isRequired,
desc: PropTypes.string.isRequired,
category: PropTypes.string.isRequired,
tags: PropTypes.arrayOf(PropTypes.string),
img: PropTypes.string.isRequired
}).isRequired
).isRequired,
}
export default EventList
./ containers / EventListHandler
import { connect } from 'react-redux'
import {fetchEvents, receivedEvents} from '../actions/eventAction'
import EventList from '../components/EventList'
import {C} from '../actions/actionType'
const getEvents = (events, actionType) => {
switch(actionType) {
case C.RECEIVED_EVENTS:
return events
default:
throw new Error('Errorororor!')
}
}
const mapStateToProps = state => {
return {
events: getEvents(state.events, C.RECEIVED_EVENTS )
}
}
const mapDispatchToProps = dispatch => {
return ({
fetchEvents: () => {dispatch(receivedEvents)}
})
}
const ShowEventList = connect(
mapStateToProps,
mapDispatchToProps
)(EventList)
export default ShowEventList
./ reducers / eventReducer.js
import {C} from '../actions/actionType';
export default (state = [], action) => {
switch (action.type){
case C.RECEIVED_EVENTS:
return [
...state,
Object.assign({}, action.payload)
];
default:
return state;
}
};
./ reducers / index.js
import { combineReducers } from 'redux';
import EventReducer from './eventReducer';
export const rootReducer = combineReducers({
events: EventReducer
});
export default rootReducer;
和错误消息:
警告:道具类型失败:道具
events
被标记为EventList
,但其值为undefined
。 在EventList中
更新: src / index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Place, Time} from './plan';
import {Event} from './containers/EventListHnadler'
import * as serviceWorker from './serviceWorker';
import { Provider } from 'react-redux';
import configureStore from './store/configureStore';
import rootReducer from './reducers/index'
const store = configureStore(rootReducer);
ReactDOM.render(
<Provider store={store}>
<Event />
</Provider>, document.getElementById('event-entry'));
ReactDOM.render(<Place />, document.getElementById('select-place'))
ReactDOM.render(<Time />, document.getElementById('select-time'))
serviceWorker.register();
答案 0 :(得分:1)
我真的不确定您在哪里使用此ShowEventList
但是只要有条件就可以使用
render(){
<div>
{
events && events.length>0 &&
<ShowEventList events={this.events} />
}
</div>
}
这将确保您的EventList
组件始终收到道具