Reputation: 445
I'm trying to create a table with React that will receive JSON data eventually (via HTTP request). I am currently storing the data in the state of my first component, and then rendering the table in my second component.
I would like each row in my table to contain an image of an album cover, followed by text data about the track, artist, and album title. For this post, I will include one row of my data so that you may see how it is stored in state.
I am currently unable to render an image stored as a string in state. What could I changed about my getRowsData() function in order to make this work? Or maybe I need to change how I am calling my image string? Any help or advice would be greatly appreciated.
The state (with image string as a .jpeg file) is found here:
import React, { Component, useState, Fragment } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import AudioPlayer from './AudioPlayer';
import Table from './Table/TrackInfo';
import '../components/AudioPlayer.css';
import '../adrian_trinkhaus.jpeg';
export default class PostContent extends Component {
constructor(props) {
super(props);
this.state = {
tracklist: this.props.tracklist,
data: [
{
'Album Art': '../adrian_trinkhaus.jpeg',
'Artist': 'The Olivia Tremor Control',
'Track Title': 'The Opera House',
'Album Title': 'Music From The Unrealized Film Script: Dusk At Cubist Castle'},
]
}
}
render() {
console.log(this.props.tracklist)
return (
<Fragment>
{/*Audio Player and Related*/}
<AudioPlayer />
<Link id='home-link' to='/' activeClassName='active'>Homepage</Link>
<div className="word-content">
<h2 className="show-title">{this.props.showTitle}</h2>
<div className="episode-post-content">{this.props.content}</div>
<Table data={this.state.data} />
<div className="bottom-link">
<Link id='home-link' to='/' activeClassName='active'>Homepage</Link>
</div>
</div>
</Fragment>
)
}
}
The table is created here:
import React, { Component } from 'react';
export default class Table extends React.Component {
constructor(props) {
super(props);
this.getHeader = this.getHeader.bind(this);
this.getRowsData = this.getRowsData.bind(this);
this.getKeys = this.getKeys.bind(this);
}
getKeys = function () {
return Object.keys(this.props.data[0]);
}
getHeader = function () {
var keys = this.getKeys();
return keys.map((key, index) => {
return <th key={key}>{key.toUpperCase()}</th>
})
}
getRowsData = function () {
var items = this.props.data;
var keys = this.getKeys();
return items.map((row, index) => {
return <tr key={index}><RenderRow key={index} data={row} keys={keys} /></tr>
})
}
render() {
return (
<div>
<table>
<thead>
<tr>{this.getHeader()}</tr>
</thead>
<tbody>
{this.getRowsData()}
</tbody>
</table>
</div>
);
}
}
const RenderRow = (props) => {
return props.keys.map((key, index) => {
return <td key={props.data[key]}>{props.data[key]}</td>
})
}
Upvotes: 0
Views: 2607
Reputation: 5133
You have to use HTML <image>
element to display images so in your RenderRow
function try to do this modification
const RenderRow = (props) => {
return props.keys.map((key, index) => {
return(
<td key={props.data[key]}>
<img src={props.data.Album Art} alt="Album Art" className="yourCustomStyle"/>
<div>{props.data.Artist}</div>
<div>{props.data.Track Title}</div>
</td>
)})
}
TIP:
In
Table
class instead of bindingthis
to every function you can convert those functions to arrow functions which bindsthis
automatically to a function. It will make your code shorter and cleaner. So to convert a function into arrow function all you have to do is this
functionName = (arguments) => {
console.log("This is an arrow function")
}
Do this to all your functions and remove this
binding in the constructor.
Hope it helps
Upvotes: 1