response.data not rendering in the browser
Closed this issue · 18 comments
Hiya! So I want my data from my API to render as a paragraph on my /home path however it's blank right now. I console logged my get request and it is getting a response. What else am I missing?
src/App.js
import React, { Component } from 'react';
import {
BrowserRouter as Router,
Route,
Link,
Redirect
} from "react-router-dom"
import axios from "axios"
import './App.css'
import Dashboard from './Components/Dashboard/Dashboard'
class App extends Component {
constructor(props){
super(props)
this.state = {
posts: []
}
}
componentDidMount(){
axios.get("http://localhost:3001/api/categories").then((response) => {
console.log(response.data);
this.setState({
posts: response.data
})
})
}
render() {
return (
<Router>
<div>
<nav>
<Link to="/home">Home</Link>
<Link to="/categories">Swap</Link>
</nav>
<main>
<Route
path="/home"
render={ () => {
return(
<Dashboard posts={this.state.posts}/>
)
}}
/>
</main>
</div>
</Router>
);
}
}
export default App;
src/Component/Dashboard/Dashboard.js
import React, { Component } from 'react';
// import { Link } from "react-router-dom"
class Dashboard extends Component {
render(){
return(
<p>{this.props.posts}</p>
)
}
}
export default Dashboard
assuming your post
s have body
and title
properties...
class Dashboard extends Component {
render(){
let posts = this.props.posts.map( post => {
return (
<div>
<h3>{post.title}</h3>
<p>{post.body}</p>
</div>
)
})
return(
<p>{posts}</p>
)
}
}
edit: added div wrapper to the return of the map callback function.
you'll want something like that. Otherwise, it's trying to render the this.props.posts
which is an instance of Array
Does that make sense? you were trying to render the array itself rather than a component/html (.jsx
objects) containing data from the objects in the array.
Hey how is this going?
Oh sorry I forgot to reply! It's working fine now thank yoU!
Oh no I spoke too soon! It's broken again
here is my code for Post.js
import React, { Component } from 'react';
import { Link } from "react-router-dom"
class Post extends Component {
constructor(props){
super(props)
this.state = {
post: this.props.location.state.type
}
}
render(){
let singlepost = this.state.post.posts.map((item, indexKey)=>{
console.log(this.state.post.posts)
let itemroute = `/categories/${this.state.post.type}/${item.item_name}`
return(
<div key={indexKey}>
<p><Link to={{
pathname: itemroute,
state: {item: item}
}}>{item.item_name}</Link></p>
</div>
)
})
return(
<div>
{singlepost}
</div>
)
}
}
export default Post
Where are you passing props to Post
? Can you post that code?
import React, { Component } from 'react';
import { Link } from "react-router-dom"
class Dashboard extends Component {
render(){
let posts = this.props.posts.map((post, indexKey)=>{
let showroute = `/categories/${post.type}`
return(
<div key={indexKey}>
<p><Link to={{
pathname: showroute,
state: {type: post}
}}>{post.type}</Link></p>
</div>
)
})
return(
<div>{posts}</div>
)
}
}
export default Dashboard
So in my .map function in Post.js I'm trying to iterate through my array for posts property in my json data
Can you link your Route where you are passing props
to your Post
component?
<main>
<Route
path="/home"
render={ () => {
return(
<Dashboard posts={this.state.posts}/>
)
}}
/>
<Route
path="/categories/:type"
component={Post}
/>
<Route
path="/categories/:type/:item_name"
component={SinglePost}
/>
</main>
That's in App.js
right?
yup! and here is also my SinglePost.js code:
import React, { Component } from 'react'
class SinglePost extends Component {
constructor(props){
super(props)
this.state = {
item: this.props.location.state.item
}
}
render(){
return(
<div>
<h2>{this.state.item.item_name}</h2>
<p>{this.state.item.description}</p>
<p>{this.state.item.location}</p>
<img src={this.state.item.image_url} alt="{this.state.item.item_name}"/>
</div>
)
}
}
export default SinglePost
It looks like you're just passing route props since you are just using Route
's component
prop.
You should instead use render to compose <Post />
and pass it props
.
Closing for now, reopen if necessary