Redux中的mapStateToProps存在问题,它认为变量未定义。代码如下。我对Redux和JavaScript还是陌生的,因此,如何解决此问题实际上没有任何意义。对于上下文,我试图将此Reddit组件呈现为网站的页面之一,但是我遇到了这个问题,并且不知道如何进行。
Reddit.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { selectSubreddit, fetchPostsIfNeeded, invalidateSubreddit } from '../actions'
import Picker from './Picker'
import Posts from './Posts'
import {Button, ListGroup} from 'react-bootstrap';
class Reddit extends Component {
static propTypes = {
selectedSubreddit: PropTypes.string.isRequired,
posts: PropTypes.array.isRequired,
isFetching: PropTypes.bool.isRequired,
lastUpdated: PropTypes.number,
dispatch: PropTypes.func.isRequired
}
componentDidMount() {
const { dispatch, selectedSubreddit } = this.props
dispatch(fetchPostsIfNeeded(selectedSubreddit))
}
componentDidUpdate(prevProps) {
if (prevProps.selectedSubreddit !== this.props.selectedSubreddit) {
const { dispatch, selectedSubreddit } = this.props
dispatch(fetchPostsIfNeeded(selectedSubreddit))
}
}
handleChange = nextSubreddit => {
this.props.dispatch(selectSubreddit(nextSubreddit))
}
handleRefreshClick = e => {
e.preventDefault()
const { dispatch, selectedSubreddit } = this.props
dispatch(invalidateSubreddit(selectedSubreddit))
dispatch(fetchPostsIfNeeded(selectedSubreddit))
}
render() {
const { selectedSubreddit, posts, isFetching, lastUpdated } = this.props
const isEmpty = posts.length === 0
return (
<ListGroup>
<Picker value={selectedSubreddit}
onChange={this.handleChange}
options={[ 'pokemon', 'csMajors' ]} />
<p>
{lastUpdated &&
<span>
Last updated at {new Date(lastUpdated).toLocaleTimeString()}.
{' '}
</span>
}
{!isFetching &&
<Button onClick={this.handleRefreshClick}>
Refresh
</Button>
}
</p>
{isEmpty
? (isFetching ? <h2>Loading...</h2> : <h2>Empty.</h2>)
: <div style={{ opacity: isFetching ? 0.5 : 1 }}>
<Posts posts={posts} />
</div>
}
</ListGroup>
)
}
}
const mapStateToProps = state => {
const { selectedSubreddit, postsBySubreddit } = state
const {
isFetching,
lastUpdated,
items: posts
} = postsBySubreddit[selectedSubreddit] || {
isFetching: true,
items: []
}
return {
selectedSubreddit,
posts,
isFetching,
lastUpdated
}
}
export default connect(mapStateToProps)(Reddit)
Picker.js组件
import React from 'react'
import PropTypes from 'prop-types'
const Picker = ({ value, onChange, options }) => (
<span>
<h1>{value}</h1>
<select onChange={e => onChange(e.target.value)}
value={value}>
{options.map(option =>
<option value={option} key={option}>
{option}
</option>)
}
</select>
</span>
)
Picker.propTypes = {
options: PropTypes.arrayOf(
PropTypes.string.isRequired
).isRequired,
value: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired
}
export default Picker
Post.js组件
import React from 'react'
import PropTypes from 'prop-types'
import {ListGroup, Link} from 'react-bootstrap';
const Posts = ({posts}) => (
<ListGroup>
{posts.map((post, i) =>
<ListGroup.Item Link key={i}>{post.title} <a href={post.url} >Post Link</a> </ListGroup.Item>
)}
</ListGroup>
)
Posts.propTypes = {
posts: PropTypes.array.isRequired
}
export default Posts
index.js减速器
import { combineReducers } from 'redux'
import {
SELECT_SUBREDDIT, INVALIDATE_SUBREDDIT,
REQUEST_POSTS, RECEIVE_POSTS
} from '../actions'
const selectedSubreddit = (state = 'reactjs', action) => {
switch (action.type) {
case SELECT_SUBREDDIT:
return action.subreddit
default:
return state
}
}
const posts = (state = {
isFetching: false,
didInvalidate: false,
items: []
}, action) => {
switch (action.type) {
case INVALIDATE_SUBREDDIT:
return {
...state,
didInvalidate: true
}
case REQUEST_POSTS:
return {
...state,
isFetching: true,
didInvalidate: false
}
case RECEIVE_POSTS:
return {
...state,
isFetching: false,
didInvalidate: false,
items: action.posts,
lastUpdated: action.receivedAt
}
default:
return state
}
}
const postsBySubreddit = (state = { }, action) => {
switch (action.type) {
case INVALIDATE_SUBREDDIT:
case RECEIVE_POSTS:
case REQUEST_POSTS:
return {
...state,
[action.subreddit]: posts(state[action.subreddit], action)
}
default:
return state
}
}
const rootReducer = combineReducers({
postsBySubreddit,
selectedSubreddit
})
export default rootReducer
index.js操作
export const REQUEST_POSTS = 'REQUEST_POSTS'
export const RECEIVE_POSTS = 'RECEIVE_POSTS'
export const SELECT_SUBREDDIT = 'SELECT_SUBREDDIT'
export const INVALIDATE_SUBREDDIT = 'INVALIDATE_SUBREDDIT'
export const selectSubreddit = subreddit => ({
type: SELECT_SUBREDDIT,
subreddit
})
export const invalidateSubreddit = subreddit => ({
type: INVALIDATE_SUBREDDIT,
subreddit
})
export const requestPosts = subreddit => ({
type: REQUEST_POSTS,
subreddit
})
export const receivePosts = (subreddit, json) => ({
type: RECEIVE_POSTS,
subreddit,
posts: json.data.children.map(child => child.data),
receivedAt: Date.now()
})
const fetchPosts = subreddit => dispatch => {
dispatch(requestPosts(subreddit))
return fetch(`https://www.reddit.com/r/${subreddit}.json`)
.then(response => response.json())
.then(json => dispatch(receivePosts(subreddit, json)))
}
const shouldFetchPosts = (state, subreddit) => {
const posts = state.postsBySubreddit[subreddit]
if (!posts) {
return true
}
if (posts.isFetching) {
return false
}
return posts.didInvalidate
}
export const fetchPostsIfNeeded = subreddit => (dispatch, getState) => {
if (shouldFetchPosts(getState(), subreddit)) {
return dispatch(fetchPosts(subreddit))
}
}
Redux中的mapStateToProps存在问题,它认为变量未定义。代码在下面。
我对Redux和JavaScript还是陌生的,因此,如何解决此问题实际上没有任何意义。对于上下文,我试图将此Reddit组件呈现为网站的页面之一,但是我遇到了这个问题,并且不知道如何进行。
Redux中的mapStateToProps存在问题,它认为变量未定义。代码如下。我对Redux和JavaScript还是陌生的,因此,如何解决此问题实际上没有任何意义。
对于上下文,我试图将此Reddit组件呈现为网站的页面之一,但是我遇到了这个问题,不知道如何继续.Redux中的mapStateToProps有一个问题,它认为变量未定义
代码在下面。我对Redux和JavaScript还是陌生的,因此,如何解决此问题实际上没有任何意义。
对于上下文,我试图将此Reddit组件呈现为网站的页面之一,但是我遇到了这个问题,并且不知道如何进行。
Redux中的mapStateToProps存在问题,它认为变量未定义。代码在下面。
我对Redux和JavaScript还是陌生的,因此,如何解决此问题实际上没有任何意义。
对于上下文,我试图将此Reddit组件呈现为网站的页面之一,但是我遇到了这个问题,并且不知道如何进行。
答案 0 :(得分:0)
您实际上没有说未定义哪个变量,这是问题中的一个重要细节。但是,我不知所措,并且猜测它是posts
,因为它第一次出现在mapStateToProps
的return语句中:
return {
selectedSubreddit,
posts, <----- never defined
isFetching,
lastUpdated
}
您是说items
吗?您会麻烦将其从selectedSubreddit
对象中拉出,但不要在返回中包括它。