这是我已经坚持了两个多星期的事情,所以这个问题是我最后的机会来解决这个问题。我希望任何人都可以帮助我(因为问题很可能是小事/我错过了什么)
使用Node,Redux和React,我从Mongo数据库返回一个集合。 我正在使用react-redux" connect"从我的商店中检索我的数据如下面的JSX中所示。
JSX:
import React from "react";
import {connect} from "react-redux"
import {fetchArticle} from "../../actions/articleActions"
var classNames = require('classnames');
import GlobalHero from '../modules/GlobalHero.jsx';
@connect((store) => {
return {article: store.article.article, fetching: store.article.fetching};
})
export default class Article extends React.Component {
// BEFORE COMPONENT RENDER (For Everyhing else)
constructor() {
super();
//sets initial state
this.state = {
page: "Article"
};
}
// BEFORE COMPONENT RENDER (For Ajax / Dispatcher Events): get article Title / Thumbnail rows based on this.props.indexLimit
componentWillMount = () => {
console.log(this.props)
this.props.dispatch(fetchArticle(this.props.params.id))
}
// ON COMPONENT RENDER
componentDidMount = () => {}
render() {
if (this.props.fetching) {
return (
<p>Loading...</p>
);
} else {
return (
<div>
<h1>{this.props.article.title}</h1>
<h2>{this.props.article.subTitle}</h2>
</div>
);
}
}
}
我的问题:
所以当我回归&#34; title&#34;和&#34; subTitle&#34;在我的JSX中,它可以完美地完成所有操作(见下文):
<h1>{this.props.article.title}</h1>
<h2>{this.props.article.subTitle}</h2>
我的屏幕上也会显示数据(见下文):
但是......一旦我补充道:
<h3>{this.props.article.body.section1.text}</h3>
我的页面无法加载,我的控制台会返回:
无法读取属性&#39; section1&#39;未定义的
当我在控制台中查看返回数据的状态时:
如您所见,它会返回&#39; section1&#39;在控制台中,所以我必须打电话给我的第1部分&#39;我的JSX错了吗?
我认为问题可能与“第1节&#39;第1节&#39;进一步嵌套到我的mongo db集合中而不是&#39; title&#39;或者&#39; subTitle&#39;是
下面我将向您展示此页面的其余路线 - 我在网上无休止地查看,无法查明我的问题。
动作:
import axios from "axios";
//var resourceUrl = "http://localhost:7777/api/schools";
export function fetchArticle(id) {
return function(dispatch) {
dispatch({
type: "FETCH_ARTICLE"
})
axios.get('/api/article', {
params: {
id: id
}
})
.then((response) => {
dispatch({
type: "FETCH_ARTICLE_FULFILLED",
payload: response.data
})
})
.catch((err) => {
dispatch({
type: "FETCH_ARTICLE_REJECTED",
payload: err
})
})
}
}
减速机:
export default function reducer(state = {
article: [],
fetching: false,
fetched: false,
error: null,
}, action) {
switch (action.type) {
case "FETCH_ARTICLE":
{
return {
...state,
fetching: true
}
}
case "FETCH_ARTICLE_REJECTED":
{
return {
...state,
fetching: false,
error: action.payload
}
}
case "FETCH_ARTICLE_FULFILLED":
{
return {
...state,
fetching: false,
fetched: true,
article: action.payload,
}
}
}
return state
}
商品
import {
applyMiddleware,
createStore
} from "redux"
import logger from "redux-logger"
import thunk from "redux-thunk"
import promise from "redux-promise-middleware"
import reducer from "./reducers"
const middleware = applyMiddleware(promise(), thunk, logger())
export default createStore(reducer, middleware)
节点/快速呼叫:
app.get('/api/article', (req, res) => {
var ObjectId = require('mongodb').ObjectID;
var articles;
db.collection('articles')
.findOne({
"_id": ObjectId("58c2a5bdf36d281631b3714a")
})
.then(result => {
articles = result;
}).then(() => {
res.send(articles);
}).catch(e => {
console.error(e);
});
});
我的mongo数据库集合中的记录:
{
"_id": {
"$oid": "58c2a5bdf36d281631b3714a"
},
"title": "EntertheBadJah",
"subTitle": "Lorem ipsum dolor",
"thmbNailImg": "",
"headerImg": "",
"body": {
"section1": {
"include": true,
"text": "Lorem ipsum dolor sit amet, dico posse integre cum ut, praesent iudicabit tincidunt te sea, ea populo semper laoreet duo."
},
"section2": {
"include": true,
"text": "Lorem ipsum dolor sit amet, dico posse integre cum ut, praesent iudicabit tincidunt te sea, ea populo semper laoreet duo."
},
"bodyImg": {
"include": true,
"img": ""
},
"section3": {
"include": true,
"text": "Lorem ipsum dolor sit amet, dico posse integre cum ut, praesent iudicabit tincidunt te sea, ea populo semper laoreet duo."
}
},
"links": {
"recourse": {
"include": false,
"text": "Go watch their interview",
"link": ""
},
"soundcloud": {
"include": true,
"link": "www.soundcloud.com/BadJah"
},
"spotify": {
"include": false,
"link": ""
},
"youtube": {
"include": false,
"link": ""
},
"twitter": {
"include": false,
"link": ""
},
"facebook": {
"include": false,
"link": ""
},
"instagram": {
"include": false,
"link": ""
}
},
"keywords": "Badjah",
"date": "",
"author": "Aagentah",
"dateAdded": "2017-06-01T00:00:00.000Z"
}
对此问题的任何帮助或建议表示赞赏 - 谢谢你提前。
答案 0 :(得分:5)
当其道具(通过Redux connect提供)发生变化时,React将重新呈现该页面。由于您只是触发了在componentWillMount
中获取数据的请求,因此根据定义,这将不会在第一次渲染时完成。但是,在第一种情况下没有问题,因为this.props.article
保证是一个对象,[]
,所以this.props.article.title
将只是undefined
。一旦API请求返回,就会在商店中更新article
,并使用预期内容呈现页面。
但是,由于this.props.article
最初是[]
,如果您尝试呈现this.props.article.body.section1.text
,您的代码将抛出异常,因为虽然article
是一个对象,{ {1}}是article.body
。已经抛出错误,当文章在商店中实际更新时,组件将无法重新呈现。
在尝试渲染子项之前,您需要添加一个防护来检查undefined
的形状,或者在请求返回实际文章之前为存储添加更完整的默认值。
答案 1 :(得分:1)
尝试这样的事情。可能是在第一个渲染周期中它还没有出现。
checkRender(){
typeof this.props.article.body === 'undefined'
? return null
: return this.props.article.body.section1.text
}
然后使用它::&gt;
<h3>{checkRender}</h3>
答案 2 :(得分:1)
我绝对可以建议在代码库中添加Flow类型检查(http://flow.org)。它可以基于每个文件的文件添加,但可以显着地帮助调试这些问题。