2

im newbie in React and trying to make a headless worpdpress aplication. when i fetch a post i get only the first value.

I fetch the post and save it in the state

componentDidMount() {
this.setState({ loading: true }, () => {
  axios.get('http://localhost/wpprojekte/ebike/wp-json/wp/v2/posts/426')
    .then(res => {
      this.setState({ loading: false, error: 'no error', post: res.data })
    }).catch(error => {
      console.log(error);
    });
});}

I have now the post in my state which looks like

constructor(props) {
super(props);
this.state = {
  loading: false,
  error: 'error',
  post: {},
}}

when i render the Component, i can get only the first value from the post. for example this.state.post.date

when i try to get this.state.post.title.rendered

Uncaught TypeError: Cannot read properties of undefined (reading 'rendered')

here is The render function

render() {
console.log(JSON.stringify(this.state.post));
return (
  <div>
    {<div dangerouslySetInnerHTML={{ __html: this.state.post.title.rendered }} />}
  </div>
)}

I dont understand why it is getting only the first value.

this is the console log

  "id": 426,
  "date": "2021-05-07T09:49:37",
  "date_gmt": "2021-05-07T09:49:37",
  "guid": {
    "rendered": "http://localhost/wpprojekte/ebike/?post_type=genusstouren&#038;p=426"
  },
  "modified": "2021-11-30T11:00:28",
  "modified_gmt": "2021-11-30T11:00:28",
  "slug": "schoeningen-helmstedt",
  "status": "publish",
  "type": "genusstouren",
  "link": "http://localhost/wpprojekte/ebike/genusstouren/schoeningen-helmstedt/",
  "title": {
    "rendered": "Genuss Bike Paradies Etappe 10"
  },
  "content": {
    "rendered": "\n<p><strong>Diese Etappe startet in Schöningen und führt am Lappwaldsee durch Helmstedt und den angrenzenden Lappwald nach Wolfsburg.</strong></p>\n\n\n\n<p>Die Route beginnt am Burgplatz nahe des Schlosses Schöningen und führt am ehemaligen Tagebau entlang in Richtung Norden. Dort führt die Tour westlich am Lappwaldsee entlang nahe des Grenzübergangs Helmstedt/Marienborn, welcher der größte und bedeutendste Grenzübergang an der innerdeutschen Grenze war. Von Helmstedt aus, in dessen Altstadt noch immer Teile der Stadtmauer als Wallanlagen zu finden sind, folgt die Route dem Lappwald, führt durch bewaldetes Gebiet und am Kloster Mariental durch Grasleben wieder in westlichere Richtung. Über Feldwege und durch kleinere Ortschaften geht es nach Velpke und von dort aus durch die Velpker Schweiz nach Oebisfelde. Nach Grafhorst und Überquerung der Aller führt die Route am Naturschutzgebiet Wendschotter und Vorsfelder Drömling entlang nach Wolfsburg, wo die Etappe am Wissenschaftsmuseum phaeno endet.</p>\n\n\n\n<p></p>\n\n\n\n<script type=\"text/javascript\" src=\"https://regio.outdooractive.com/oar-harz/de/embed/55540446/js?mw=false\"></script>\n",
    "protected": false
  },
  "excerpt": {
    "rendered": "<p>Diese Etappe startet in Schöningen und führt am Lappwaldsee durch Helmstedt und den</p>\n<div class=\"mehr-erfahren\"><a href=\"http://localhost/wpprojekte/ebike/genusstouren/schoeningen-helmstedt/\" rel=\"nofollow\"><icon class=\"fas fa-angle-double-right\"></icon> mehr erfahren</a></div>\n",
    "protected": false
  },
  "author": 2,
  "featured_media": 442,
  "parent": 0,
  "menu_order": 0,
  "template": "",
  "meta": [],
  "featured_image_src": "http://localhost/wpprojekte/ebike/wp-content/uploads/2021/05/Etappe_10.jpg",
  "_links": {
    "self": [
      {
        "href": "http://localhost/wpprojekte/ebike/wp-json/wp/v2/genusstouren/426"
      }
    ],
    "collection": [
      {
        "href": "http://localhost/wpprojekte/ebike/wp-json/wp/v2/genusstouren"
      }
    ],
    "about": [
      {
        "href": "http://localhost/wpprojekte/ebike/wp-json/wp/v2/types/genusstouren"
      }
    ],
    "author": [
      {
        "embeddable": true,
        "href": "http://localhost/wpprojekte/ebike/wp-json/wp/v2/users/2"
      }
    ],
    "version-history": [
      {
        "count": 3,
        "href": "http://localhost/wpprojekte/ebike/wp-json/wp/v2/genusstouren/426/revisions"
      }
    ],
    "predecessor-version": [
      {
        "id": 1065,
        "href": "http://localhost/wpprojekte/ebike/wp-json/wp/v2/genusstouren/426/revisions/1065"
      }
    ],
    "wp:featuredmedia": [
      {
        "embeddable": true,
        "href": "http://localhost/wpprojekte/ebike/wp-json/wp/v2/media/442"
      }
    ],
    "wp:attachment": [
      {
        "href": "http://localhost/wpprojekte/ebike/wp-json/wp/v2/media?parent=426"
      }
    ],
    "curies": [
      {
        "name": "wp",
        "href": "https://api.w.org/{rel}",
        "templated": true
      }
    ]
  }
}
Youssef Ouarrak
  • 47
  • 1
  • 2
  • 9

2 Answers2

3

SOLUTION

The reason you are getting the error is because componentDidMount is called after your render method is called that is your UI is rendered before your post is fetched, how does it relate to the error ? Now this is it. from your code calling this.state.post.date returns null which is empty and doesnt cause any issue because from react lifecycle render method is called first before componentDidMount but calling this.state.post.title.rendered when post is not fetched or is not available on state does the following, first it checks this.state.post.title which is null which could just work as that of the date but calling .rendered on the null will now throw the error you are getting. to make sure you dont get into such error you have to make sure title is defined or post is set on state

CODE SOLUTION

replace your render with this one.

render() {
return (
  <div>
    {
      this.state.post.title && (
      <div dangerouslySetInnerHTML={{ __html: this.state.post.title.rendered }} />)
    }
  </div>
)}
solomon Yunana
  • 409
  • 3
  • 6
  • thank you that works well, i also have the same problem with `this.props.match.params`, it is always undefined, could it also be the same reason? – Youssef Ouarrak Jan 13 '22 at 15:23
  • are you trying to access params of a route in **react-router-dom** ? – solomon Yunana Jan 13 '22 at 15:41
  • yes exactly, this my route `} />` i am passing id. in my MainComponent i have a link to go to single Post id `Read more` i need to get this param (id) inside componentDidMount() – Youssef Ouarrak Jan 13 '22 at 16:02
  • change `path="post"` to `path="/post"` and change `path=":postid"` to `path="/:postid"` if it doesnt work, send the version of react-router dom you are using so i can check it out on a demo react environment – solomon Yunana Jan 13 '22 at 18:00
  • here is where my Routes are ` } /> } /> ` in The Content Componenet, you find a Link `Read more` in The Post Component i have the componentDidMount() as i post in the question. and still dont know how to get the ID – Youssef Ouarrak Jan 13 '22 at 18:25
  • was That enough or should i give you more? – Youssef Ouarrak Jan 14 '22 at 12:49
  • if possilbe more and the version of react-router-dom – solomon Yunana Jan 14 '22 at 13:05
  • i cant really provide more from the Code, i just want to mention, that im using a Class Component and not a Funktion "react-router": "^6.2.1", "react-router-dom": "^6.2.1", – Youssef Ouarrak Jan 14 '22 at 13:48
  • ok i think i have enough to reproduce your problem – solomon Yunana Jan 14 '22 at 14:12
  • 1
    Thank you!! i finally solve it. if anyone has the same trouble. Make sure that your installed React-dom is updated. In react-router-dom v6 the Route components no longer have route props (history, location, and match), and the current solution is to use the React hooks "versions" of these to use within the components being rendered. React hooks can't be used in class components though. so you need to convert your Class to function. and use `useParams()`. – Youssef Ouarrak Jan 14 '22 at 14:50
0

In my case, it was due to the redux dev tool not installed and i have added dev tool option while creating redux store. After Installing dev tool extension it worked for me