【发布时间】:2018-09-20 17:08:27
【问题描述】:
在我的 localhost react-node 应用程序中,当我点击 Movies.js 页面时,该应用程序将对 {localhost}/api/movies 节点端点进行 api 调用(顺便说一句,我正在使用 redux-thunk 中间件)。
然后它将一个 json 返回到 this.props.movies.displayedMovies(入口点是 componentDidMount()),然后将其传递给 render()。
从那以后,唯一的变化是我添加了另一个reducer MusicReducer 并使用redux 的combinedReducer(..) 来配置store。
现在,电影页面呈现空白,因为控制台返回 Cannot read property 'displayedMovies' of undefined 并且似乎没有调用 componentDidMount。
不确定是什么问题。下面是代码。任何帮助,将不胜感激。
Movies.js 容器
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as moviesActions from '../actions/MoviesActions'
import NavBar from '../components/NavBar'
import ResultsBar from '../components/ResultsBar'
import Grid from '../components/Grid'
import * as utils from '../utils/utils.js'
import style from '../style/App.css'
class Movies extends Component {
handleSearch(e) {
this.props.moviesActions.filterMovies(e.target.value)
}
componentDidMount() {
this.props.moviesActions.fetchMovies()
}
render() {
let { displayedMovies } = this.props.movies
return (
<div>
<NavBar onChange={this.handleSearch.bind(this)} type={0}/>
<br/>
<ResultsBar count={displayedMovies.length} type={0}/>
<Grid
gridData={JSON.stringify(displayedMovies)}
gridCell_width={140}
gridCell_height={200}
type={0}
/>
</div>
);
}
}
function mapStateToProps(state) {
return {
movies: state.movies
}
}
function mapDispatchToProps(dispatch) {
return {
moviesActions: bindActionCreators(moviesActions, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Movies)
MoviesActions.js 动作
import {
REQUEST_MOVIES,
RECEIVE_MOVIES,
FILTER_MOVIES,
SORT_MOVIES
} from '../constants/Page'
import * as utils from '../utils/utils.js'
function requestMovies() {
return {
type: REQUEST_MOVIES
}
}
function receiveMovies(json) {
return {
type: RECEIVE_MOVIES,
movies: json
}
}
export function fetchMovies() {
return dispatch => {
dispatch(requestMovies())
utils.callApi('/api/movies')
.then(items => {
var data = [];
for (var i = 0; i < items.length; i++) {
data.push({
tmdb_id: items[i].id,
imdb_id: items[i].imdb_id,
title: items[i].title,
poster_path: 'https://image.tmdb.org/t/p/w500' + items[i].poster_path,
backdrop_path: 'https://image.tmdb.org/t/p/original' + items[i].backdrop_path,
url_path: items[i].url_path,
release_date: items[i].release_date,
runtime: items[i].runtime,
revenue: items[i].revenue,
overview: items[i].overview,
tagline: items[i].tagline,
link: 'http://www.imdb.com/title/' + items[i].imdb_id
});
}
dispatch(receiveMovies(data))
})
.catch(err => console.log(err));
}
}
export function filterMovies(searchTerm) {
return {
type: FILTER_MOVIES,
searchTerm
}
}
export function sortMovies(sortOption) {
return {
type: SORT_MOVIES,
sortOption
}
}
index.js 减速器
import { combineReducers } from 'redux'
import {
BOOKS,
COMICS,
MOVIES,
MUSIC,
PODCASTS,
TV
} from '../constants/Page'
import moviesReducer from './MoviesReducer'
import musicReducer from './MusicReducer'
export default combineReducers({
moviesReducer,
musicReducer
})
MoviesReducer.js 减速器
import {
REQUEST_MOVIES,
RECEIVE_MOVIES,
FILTER_MOVIES,
SORT_MOVIES
} from '../constants/Page'
const initialState = {
movies: [],
displayedMovies: []
}
export default function movie(state = initialState, action) {
switch (action.type) {
case REQUEST_MOVIES:
return {
...state
}
case RECEIVE_MOVIES:
let movies = action.movies
return {
...state,
movies,
displayedMovies: movies
}
case FILTER_MOVIES:
let displayedMovies = state.movies.filter(movie => {
if (movie.title.toLowerCase().includes(action.searchTerm.toLowerCase())) {
return true
}
return false
})
return {
...state,
displayedMovies,
displayedMovies: displayedMovies
}
case SORT_MOVIES:
let sortDisplayedMovies
switch(action.sortOption) {
case 'Alphabetical':
sortDisplayedMovies = state.displayedMovies.sort((a,b)=> {
var a1 = a.title.toLowerCase();
var b1 = b.title.toLowerCase();
return a1<b1 ?-1:a1> b1? 1 :0;
})
break;
case 'Oldest':
sortDisplayedMovies = state.displayedMovies.sort((a,b)=> {
return new Date(a.release_date).getTime() - new Date(b.release_date).getTime();
})
break;
case 'Newest':
sortDisplayedMovies = state.displayedMovies.sort((a,b)=> {
return new Date(b.release_date).getTime() - new Date(a.release_date).getTime();
})
break;
default:
break;
}
return {
...state,
sortDisplayedMovies,
displayedMovies: sortDisplayedMovies
}
default:
return state
}
}
configureStore.js 存储
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers/index'
export default function configureStore() {
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
return store;
}
【问题讨论】:
标签: node.js reactjs redux react-redux