javascript - React,Redux 无法读取未定义的属性
问题描述
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 组件呈现为网站的页面之一,但我遇到了这个问题并且不知道如何继续。
解决方案
您实际上并没有说出未定义中的哪个变量,这是问题中的一个重要细节。但是,我正在四处走动并猜测这是posts
因为它mapStateToProps
第一次出现在返回语句中:
return {
selectedSubreddit,
posts, <----- never defined
isFetching,
lastUpdated
}
你的意思是items
也许吗?你会很麻烦地将它从你的selectedSubreddit
对象中拉出来,但不要将它包含在返回中。
推荐阅读
- reactjs - Jumbotron 中的按钮链接到 React 导航栏中的按钮
- python - 在 python 中使用具有并行性的 Pygame
- swift - 如何将按钮更改回其原始状态
- ios - EvaluateJavaScript 的 WKWebView 错误标头
- javascript - 如果选中复选框,用户必须输入一个值
- android - 打开带有推送通知android的特定链接
- matlab - Matlab - 如何在函数(x - sqrt(x))/ sqrt(sin(x))中x达到0时绘制极限?
- image - PageSpeed Insights、WebP 和
- nginx - 当我配置错误页面时,Nginx proxy_pass 停止工作
- java - 如何在旋转之前预测矩形的去向(处理)