我正在将React redux与Firebase实时数据库一起使用。
在App.js中,我正在调度动作fetchAllPosts
App.js
class App extends Component {
componentDidMount() {
this.props.fetchAllPosts();
}
render() {
return (
<div className="App">
// something ...
</div>
);
}
}
const mapDispatchToProps = dispatch => {
return {
fetchAllPosts: () => {dispatch(allPosts())}
}
}
我的动作如下所示(我在使用redux-thunk):
动作
export function allPosts() {
return (dispatch) => {
firebase.database().ref('posts/').on('value', (snapshot) => {
dispatch({type: "ALL_POSTS", postsArray: snapshot.val(), loading: false})
})
}
}
然后我正在组合减速器(我知道在这种情况下没有必要):
const rootReducer = combineReducers({
allPosts: postsReducer
})
我的减速器看起来像这样:
减速器
const initialState = {
allPosts: []
}
const postsReducer = (state = initialState, action) => {
switch(action.type) {
case "ALL_POSTS" :
console.log("action payload all posts", action.postsArray)
return {
...state,
loading: false,
allPosts: action.postsArray
}
break;
default:
return state
}
return state
}
最后:我的SinglePostview组件如下所示: SinglePostview.js
import React, {Component} from 'react';
import {connect} from 'react-redux';
class SinglePostview extends Component {
render() {
console.log("ppp", this.props)
return (
<h2>{this.props.post.title}</h2>
)
}
}
const mapStateToProps = (state, ownprops) => {
const postId = ownprops.match.params.postid
return {
post: state.allPosts.allPosts[postId]
}
}
export default connect(mapStateToProps)(SinglePostview);
在执行render方法时,this.props.post
未定义,并且出现错误:
TypeError:无法读取未定义的属性“ title”。
问题是:当应用程序首次加载时,props.post
是未定义的(所以我有一个错误),大约1秒钟后,它收到了值,但没有任何改变-错误仍然存在存在并且该值不显示。
有人可以帮我吗?
答案 0 :(得分:2)
假设您的减速器没问题,您可以通过以下方式解决此问题
更改此
render() {
return (
<h2>{this.props.post.title}</h2>
)
}
对此:
render() {
if (!this.props.post){
return null;
}
return (
<h2>{this.props.post.title}</h2>
)
}
或
render() {
return (
<h2>{this.props.post && this.props.post.title}</h2>
)
}
答案 1 :(得分:0)
您正在将allPosts定义为数组
const initialState = {
allPosts: []
}
但是您试图像访问对象一样访问它。
state.allPosts.allPosts[postId]
因此,如果您的state.allPosts.allPosts是一个数组,请尝试使用ES6 find()方法从具有postId的数组中获取帖子。
假设
state.allPosts.allPosts = [
{postId: 1,title:'abcd'},
{postId:2,title:'def'}
]
state.allPosts.allPosts.find(post => postId === post.postId)