2017-04-10 58 views
1

属性“XXX”这是我一直停留在超过2周,所以这个问题是我搞清楚了这一点最后的机会。我希望有人能帮助我(因为这个问题是最有可能的小东西/不是我错过了)反应,和/终极版 - 不能读取的不确定


使用节点,终极版和反应,我从我的蒙戈数据库返回集合。 我使用的反应 - 终极版“连接”从我的店取回我的数据。如下面我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> 
      ); 
     } 
    } 
} 

我的问题:

所以当我回到 “称号”,并在我的JSX “字幕”,它拉一切通过完美的罚款(见下文):

<h1>{this.props.article.title}</h1> 
    <h2>{this.props.article.subTitle}</h2> 

的数据也是我的屏幕上显示(见下图):

enter image description here

但是......只要我补充一下:

<h3>{this.props.article.body.section1.text}</h3> 

我的页面将不会加载,和我的控制台回报:

无法读取属性“ SECTION1' 的未定义

当我看到我的返回数据的控制台状态:

enter image description here

正如你所看到的,它会返回“SECTION1”在控制台上,所以我一定要打电话给我“ section1'在我的JSX中错误?

我想这个问题可能是一个事实,即“SECTION1”进一步嵌套到我的蒙戈DB收集不是“标题”或“字幕”做的是。

下面我会告诉你我的路线,其余为这个页面 - 我已经无数次在网上看了看,不能查明我的问题。

操作:

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); 
     }); 

}); 

记录在我的蒙戈DB系列:

{ 
    "_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

@barbsan - 我不这么认为,因为'section1'在'body'内。 –

+0

查看关于此问题的底部片段:title和subTitle是来自第1部分的上图层@barbsan –

+0

我对react&redux一无所知。但是这似乎很可怕,类似于我在Angular2中学习RxJS时遇到的问题。在那里我可以访问一个叫做'猫王操作员'的东西。例如:'this.props.article.body?.section1.text',它将处理加载异步的项目(它几乎看起来像section1以这种方式加载) –

回答

2

当它的道具(通过Redux connect提供)改变时,React将重新渲染页面。由于您只是触发请求获取componentWillMount中的数据,按照定义,这将不会在第一次呈现中完成。但是,在第一种情况下,这没有问题,因为this.props.article保证是对象,因此,因此this.props.article.title只是undefined。一旦对API的请求返回,article将在商店中更新,并且页面将呈现预期内容。

然而,由于this.props.article最初[],如果你尝试呈现this.props.article.body.section1.text,观察到由于同时article是一个对象,article.bodyundefined你的代码会抛出异常。在已经发生错误的情况下,组件在商店中实际更新时将无法重新渲染。

您需要在尝试渲染子项,或者增加一个更完整的默认到店里要求与实际物品返回之前之前添加保护检查的this.props.article形状。

+0

Ahhh我明白了,我应该如何在代码中添加这个警卫? –

+0

以上答案中的一个例子。 – KornholioBeavis

+0

啊,好吧,检查我的整篇文章,而不仅仅是一个对象,最好的做法是理想情况下我不想为每个属性检查函数,还是我会? –

1

尝试类似这样的东西。可能是在第一次渲染循环中它尚未出现。

checkRender(){ 
     typeof this.props.article.body === 'undefined' 
     ? return null 
     : return this.props.article.body.section1.text 
    } 

然后使用它::>

<h3>{checkRender}</h3> 
+0

呵呵,好的,检查我的整篇文章,而不仅仅是一个对象,理想情况下我不希望为每个属性检查函数,或者我会做什么? –

+1

你可以制作一个HOC,检查所有的道具,然后将它包裹在你的组件上。 – KornholioBeavis

1

我可以肯定地推荐流量类型检查添加到您的代码库(http://flow.org)。它可以基于文件逐个文件添加,但可以显着帮助调试这些类型的问题。

+0

我不知道这个 - 谢谢:) –