Im building a simple spotify app using react for the first time. Currenty I am able to render the current track being played by a user with it automatically appearing on the page. If I change tracks quickly(within a few seconds) it renders the new track details on to the page. However if I wait a couple of seconds, it stops rendering. Any reason why?
below is an example of my code
return (
<div className="App">
<a href='http://localhost:8888'>
<button>Login But With Spotify</button>
</a>
{this.getNowPlaying()}
<div> Now Playing: { this.state.nowPlaying.name} </div>
<div> By: { this.state.nowPlaying.artist} </div>
<div> Id: { this.state.nowPlaying.id} </div>
<div>
<img src={ this.state.nowPlaying.image} style={{ width: 100}}/>
</div>
</div>
)
}
Any help would be great :)
It is because you invoked the API call method "getNowPlaying" inside render method.
Each render cycle of react will call the render method, so it may be called many times.
Remove the {this.getNowPlaying()} from render and create a method "componentDidMount" and place it there. (see the code below)
The "componentDidMount" method is a react's component lifecycle method called after the component successfully mounted (initialized).
Read more in react's class component lifecycle methods docs
import React, { Component } from 'react';
import './App.css';
import Spotify from 'spotify-web-api-js';
const spotifyWebApi = new Spotify();
class App extends Component {
constructor(){
super();
const params = this.getHashParams();
this.state ={
loggedIn: params.access_token ? true : false,
nowPlaying: {
name: 'Not Checked',
image: ''
}
}
if (params.access_token){
spotifyWebApi.setAccessToken(params.access_token)
}
}
componentDidMount() {
this.getNowPlaying()
}
getHashParams() {
var hashParams = {};
var e, r = /([^&;=]+)=?([^&;]*)/g,
q = window.location.hash.substring(1);
while ( e = r.exec(q)) {
hashParams[e[1]] = decodeURIComponent(e[2]);
}
return hashParams;
}
getNowPlaying(){
spotifyWebApi.getMyCurrentPlaybackState()
.then((response) => {
this.setState({
nowPlaying: {
name: response.item.name,
image: response.item.album.images[1].url,
artist: response.item.artists[0].name,
id: response.item.id
}
})
}
)
}
render() {
return (
<div className="App">
<a href='http://localhost:8888'>
<button>Login But With Spotify</button>
</a>
<div> Now Playing: { this.state.nowPlaying.name} </div>
<div> By: { this.state.nowPlaying.artist} </div>
<div> Id: { this.state.nowPlaying.id} </div>
<div>
<img src={ this.state.nowPlaying.image} style={{ width: 100}}/>
</div>
</div>
)
}
}
Ok, this is some basic stuff.
Basically in your code, you get the new stuff on every rerender. Here there is the problem, the rerender happens only when a state, the parent or (not always) a prop changes. This can lead to some issues.
You see it working, because you change song before the This.setState is fired, so when setting the state, it triggers the component to rerender, which calls the function again. At this point, if the response has changed (basicly if you change the song), the state gets updated and this step is repeated, else, if the response is the same (didn't change the song in the meantime), the state doesn't change (leading the component not to rerender --> not refetching the data);
Here you can find the solution(s). One is class component, one is hooks (i've tested only the hooks' one). I personally would recommend the second one, because it's less code, more flexible and easier to understand!
I hope i could help you!
Class Component
import React, { Component } from 'react';
import './App.css';
import Spotify from 'spotify-web-api-js';
const spotifyWebApi = new Spotify();
class App extends Component {
constructor(){
super();
const params = this.getHashParams();
this.state ={
loggedIn: params.access_token ? true : false,
nowPlaying: {
name: 'Not Checked',
image: ''
}
}
if (params.access_token){
spotifyWebApi.setAccessToken(params.access_token)
}
}
getHashParams() {
var hashParams = {};
var e, r = /([^&;=]+)=?([^&;]*)/g,
q = window.location.hash.substring(1);
while ( e = r.exec(q)) {
hashParams[e[1]] = decodeURIComponent(e[2]);
}
return hashParams;
}
componentDidMount(){
this.getNowPlaying();
}
getNowPlaying(){
spotifyWebApi.getMyCurrentPlaybackState()
.then((response) => {
this.setState({
nowPlaying: {
name: response.item.name,
image: response.item.album.images[1].url,
artist: response.item.artists[0].name,
id: response.item.id
}
})
this.getNowPlaying();
}
)
}
render() {
return (
<div className="App">
<a href='http://localhost:8888'>
<button>Login But With Spotify</button>
</a>
<div> Now Playing: { this.state.nowPlaying.name} </div>
<div> By: { this.state.nowPlaying.artist} </div>
<div> Id: { this.state.nowPlaying.id} </div>
<div>
<img src={ this.state.nowPlaying.image} style={{ width: 100}}/>
</div>
</div>
)
}
}
Hooks
import React, { useState, useEffect, useCallback } from "react";
import "./App.css";
import Spotify from "spotify-web-api-js";
const spotifyWebApi = new Spotify();
function App() {
//not used?
const [loggedIn, setLoggedIn] = useState();
//telling whether the component is mount or not
const [isComponentMount,setIsComponentMount]=useState(true);
//response container
const [nowPlaying, setNowPlaying] = useState({
name: "Not Checked",
image: "",
artist: "",
id: ""
});
//Fetches the newest data
const getNowPlaying = useCallback(() => {
//Needed to stop the infinite loop after the component gets closed
if(!isComponentMount)return;
spotifyWebApi.getMyCurrentPlaybackState().then(response => {
setNowPlaying({
name: response.item.name,
image: response.item.album.images[1].url,
artist: response.item.artists[0].name,
id: response.item.id
});
//Change this one as you like (perhaps a timeout?)
getNowPlaying();
});
}, []);
useEffect(() => {
//Get hash params
const params = {};
var e,
r = /([^&;=]+)=?([^&;]*)/g,
q = window.location.hash.substring(1);
while ((e = r.exec(q))) {
params[e[1]] = decodeURIComponent(e[2]);
}
if (params.access_token) {
spotifyWebApi.setAccessToken(params.access_token);
}
getNowPlaying();
return ()=>{
setIsComponentMount(false);
}
}, [getNowPlaying]);
return (
<div className="App">
<a href="http://localhost:8888">
<button>Login But With Spotify</button>
</a>
<div> Now Playing: {nowPlaying.name} </div>
<div> By: {nowPlaying.artist} </div>
<div> Id: {nowPlaying.id} </div>
<div>
<img src={nowPlaying.image} style={{ width: 100 }} alt="" />
</div>
</div>
);
}
export default App
Related
So I'm trying to build a Notifications component in React. The component's state holds an array of notifications which are objects. One of their keys is 'seen'. The purpose of seen, as you can probably guess, is mainly visual. Everytime a user clicks on a notification, I run a function that's supposed to set the notification as seen in the database (for consistency) and in the local state (for UI).
The database part works great, but for some reason the state change doesn't work. When I put some console.logs, weirdly enough I see that the 'seen' property changes to 1 before I even call this.setState. I've been at it for hours now and I can't figure out what's happening.
And now, some code:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import classes from './Notifications.module.css';
import * as actions from '../../../store/actions';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import moment from 'moment';
import {Redirect} from 'react-router-dom';
class Notifications extends Component {
constructor(props) {
super(props);
// Set an interval to update notifications every 4 minutes.
this.update = setInterval(() => {
this.props.fetchNotifications(this.props.username)
}, 240000)
}
state = {
opened: false,
count: 0,
notifications: []
}
componentDidUpdate(prevProps, prevState) {
if (!prevProps.username && this.props.username) this.props.fetchNotifications(this.props.username);
if (!prevProps.notifications && this.props.notifications) {
this.setState({notifications: this.props.notifications, count: this.props.notifications.filter(not => !not.seen).length});
}
if (this.props.notifications) {
if (JSON.stringify(this.state.notifications) !== JSON.stringify(prevState.notifications)) {
this.setState({count: this.state.notifications.filter(not => !not.seen).length})
}
}
}
componentWillUnmount() {
// Clear the update interval
clearInterval(this.update);
}
redirect(model, model_id) {
switch (model) {
case 'sealant_customer':
return <Redirect to={`/profile/sealant-customer/${model_id}`} />;
case 'unapproved_business':
return <Redirect to={`/profile/unapproved-business/${model_id}`} />;
case 'business':
return <Redirect to={`/profile/business/${model_id}`} />;
case 'missed_call':
return <Redirect to={`/data/missed-calls`} />;
default: return null;
}
}
render() {
let content = (
<React.Fragment>
<div className={classes.svgWrapper}>
<p className={classes.counter} style={{opacity: this.state.count === 0 ? '0' : '1'}}>{this.state.count}</p>
<FontAwesomeIcon icon='bell' onClick={() => this.setState(prevState => ({opened: !prevState.opened}))} />
</div>
{this.state.opened && <div className={classes.notificationsWrapper}>
<ul className={classes.notificationsList}>
{this.state.notifications.length !== 0 ? Array.from(this.state.notifications).map(notifi => {
let icon;
switch (notifi.model) {
case 'sealant_customer':
case 'person':
icon = 'user';
break;
case 'business':
case 'unapproved_business':
icon = 'warehouse';
break;
default: icon = 'user';
}
let classArray = [classes.notification];
if (!notifi.seen) classArray.push(classes.unseen);
return (
<li key={notifi.id} className={classArray.join(' ')} onClick={ () => {
// If already seen, simply redirect on click.
if (notifi.seen) return this.redirect(notifi.model, notifi.model_id);
let newNotifications = [...this.state.notifications];
// If not seen, mark as seen in State & in Database.
let index = newNotifications.findIndex(not => notifi.id === not.id);
newNotifications[index].seen = 1;
this.setState({ notifications: newNotifications});
this.props.markSeen(notifi.id, this.props.username);
// Redirect.
return this.redirect(notifi.model, notifi.model_id);
}}>
<div className={classes.iconWrapper}>
<FontAwesomeIcon icon={icon} />
</div>
<div className={classes.textWrapper}>
<p className={classes.msg}>
{notifi.message}
</p>
<label className={classes.ago}>
{moment(notifi.date).fromNow()}
</label>
</div>
</li>
)
}) : <li className={classes.notification} style={{cursor: 'default'}}><p style={{whiteSpace: 'nowrap'}}>No notifications to show...</p></li>}
</ul>
</div>}
</React.Fragment>
)
return (
<div className={classes.wrapper}>
{content}
</div>
)
}
}
const mapStateToProps = state => {
return {
username: state.auth.username,
notifications: state.data.notifications
};
};
const mapDispatchToProps = dispatch => {
return {
fetchNotifications: username => dispatch(actions.fetchNotifications(username)),
markSeen: (id, username) => dispatch(actions.markSeen(id, username))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Notifications);
Any help would be appreciated.
For future readers - the SOLUTION:
The problem was that when I called the line let newNotifications = [...this.state.notifications]; I really did create a copy of notifications, but a copy which holds the original notification objects inside.
Once I changed the line newNotifications[index].seen = 1 to newNotifications[index] = {...newNotifications[index], seen: 1} everything worked like a charm.
This is bizarre. My console.log produces a company:
but for some reason in my child, when I try pulling it from props, it's null
CompanyDetailContainer
class CompanyDetailContainer extends Component {
async componentDidMount() {
const { fetchCompany } = this.props,
{ companyId } = this.props.match.params;
await fetchCompany(companyId);
}
render(){
const { company } = this.props;
console.log(company) // this outputs a company
return (
<CompanyDetail className="ft-company-detail" company={company} />
);
}
}
const mapStateToProps = state => ({
company: state.company.company
});
const mapDispatchToProps = {
fetchCompany: fetchCompany
};
export default connect(mapStateToProps, mapDispatchToProps)(CompanyDetailContainer);
CompanyDetail
export default class CompanyDetail extends Component {
render(){
const callToAction = 'test';
const { company } = this.props;
console.log(company) // this is null! why??? I've never had this problem before
const title = `${company.name} Details`;
return (
<Main>
<MainLayout title={title}>
<div>
<div id='ft-company-detail'>
<div className="panel vertical-space">
<CompanyHeader className="ft-company-header" company={company} />
<div className="ft-call-to-action-interview">{callToAction}</div>
<CompanyProfile className="ft-company-profile" company={company} />
<RelatedLinks className="ft-company-resources" company={company} />
</div>
</div>
</div>
</MainLayout>
</Main>
);
}
}
///// UPDATE ////
this worked:
return (
company && <CompanyDetail className="ft-company-detail" company={company} />
);
But then why does this combo work fine? it's setup pretty much the same way. This is the first route hit on my app, renders this container:
HomepageContainer
class HomePageContainer extends Component {
async componentDidMount() {
await this.props.fetchFeaturedCompanies();
await this.props.fetchCompanies();
await this.props.fetchCountries();
}
render(){
return (<HomePage
className='ft-homepage'
companies={this.props.companies}
countries={this.props.countries}
featuredCompanies={this.props.featuredCompanies}
/>);
}
}
const mapStateToProps = state => ({
countries: state.country.countries,
companies: state.company.companies,
featuredCompanies: state.company.featuredCompanies
});
const mapDispatchToProps = {
fetchCountries: fetchCountries,
fetchCompanies: fetchCompanies,
fetchFeaturedCompanies: fetchFeaturedCompanies
};
export default connect(mapStateToProps, mapDispatchToProps)(HomePageContainer);
HomePage
export default class HomePage extends Component {
render(){
return (
<Main>
<MainLayout title='Test'>
<div className="homepage panel vertical-space margin-bottom-300">
<FeaturedCompanies companies={this.props.featuredCompanies} />
<div>
<div className="column-group">
<div className="all-100 width-100 align-center fw-300 extralarge">
test
</div>
</div>
</div>
<CompanyList className="ft-company-list" companies={this.props.companies} countries={this.props.countries} />
</div>
</MainLayout>
</Main>
);
}
}
To the fella who commented on my theme, the first image above is from Chrome tools dark theme. Here is my actual theme in WebStorm which I think is even better :P:
componentDidMount is called after the render and your async call is in the componentDidMount, so for the first render the parent and the child both get null, and since you use company.name in child without a conditional check it errors out. Provide a conditional check in the child and it will work fine
const { company } = this.props;
console.log(company)
const title = company ? `${company.name} Details`: null;
When this component is called I get the follow error.
setState(...): Cannot update during an existing state transition (such
as within render or another component's constructor). Render methods
should be a pure function of props and state; constructor side-effects
are an anti-pattern, but can be moved to componentWillMount.
It seems to be because { this.renderCurrentAthlete() } inside render. When I call renderCurrentAthlete I'm trying to let state know who the current Athlete is by running the this.setState({ currentAthlete: currentAthleteData.Athlete }) but it causes an error. Any advise on how to handle this properly? Also any other advise on the component would be awesome too! Learning so all info is a great help :)
class MiniGame extends Component {
constructor(props){
super(props);
this.state = {
score: 0,
currentAthlete: null
}
}
gameData = [
{Athlete: "Peyton Manning", Img: "someURL"},
{Athlete: "Tony Hawk", Img: "someURL"},
{Athlete: "Tomy Brady", Img: "someURL"},
{Athlete: "Usain Bolt", Img: "someURL"}
]
renderGameButtons() {
return(
<div>
{this.gameData.map((x) => {
return(
<div key={x.Athlete}>
<button className="btn btn-outline-primary" onClick={ () => this.answerHandler(x.Athlete)}> {x.Athlete} </button>
</div>
)
})}
</div>
)
}
renderCurrentAthlete() {
const currentAthleteData = this.gameData[Math.floor(Math.random() * 4)];
//console.log(currentAthleteData);
const imgUrl = currentAthleteData.Img;
const athleteName = currentAthleteData.Athlete;
console.log(imgUrl, athleteName);
//console.log(currentAthlete);
this.setState({ currentAthlete: currentAthleteData.Athlete });
return(
<img className="card-img-top imgCard" src={imgUrl} alt="..."></img>
)
}
answerHandler(answer){
// console.log(a)
// console.log(this.state.currentAthlete)
if(answer === this.state.currentAthlete) {
this.setState({score: this.state.score + 10})
console.log(this.state.score);
}
}
render(){
return(
<div className="miniGameContainer">
<div className="card card-outline-info mb-3">
{ this.renderCurrentAthlete() }
<div className="card-block">
<p className="card-text">Pick your Answer Below</p>
{ this.renderGameButtons() }
</div>
</div>
</div>
)
}
}
Add method componentWillMount put this code to it and remove from renderCurrentAthlete. method componentWillMount will invoke before render. See more react lifecycle
componentWillMount() {
const currentAthleteData = this.gameData[Math.floor(Math.random() * 4)];
//console.log(currentAthleteData);
const imgUrl = currentAthleteData.Img;
const athleteName = currentAthleteData.Athlete;
console.log(imgUrl, athleteName);
//console.log(currentAthlete);
this.setState({ currentAthlete: currentAthleteData.Athlete });
}
First watch this, so you can see the behavior going on.
Timing Issue (JS in one component relies on another component to exist first)
I need to be able to somehow check that another component exists before I apply this JS in this component's ComponentDidMount
const TableOfContents = Component({
store: Store('/companies'),
componentDidMount() {
const el = ReactDOM.findDOMNode(this);
console.log("table of contents mounted");
if(document.getElementById('interview-heading') && el) {
new Ink.UI.Sticky(el, {topElement: "#interview-heading", bottomElement: "#footer"});
}
},
it does hit my if statement and does hit the Sticky() function but I still think I have problems when I refresh the page whereas this JS isn't working on the interview-heading component for some reason.
Note the id="interview-heading" below.
const InterviewContent = Component({
componentDidMount() {
console.log("InterviewContent mounted");
},
render(){
var company = this.props.company;
return (
<div id="ft-interview-content">
<p className="section-heading bold font-22" id="interview-heading">Interview</p>
<InterviewContentMain company={company}/>
</div>
)
}
})
const InterviewContentMain = Component({
componentDidMount() {
console.log("InterviewContentMain mounted");
},
render(){
var company = this.props.company;
return (
<div id="interview-content" className="clear-both">
<div className="column-group">
<div className="all-20">
<TableOfContents company={company}/>
</div>
<div className="all-80">
<InterviewContainer company={company}/>
</div>
</div>
</div>
)
}
})
export default InterviewContent;
I realize TableOfContents is being rendered before InterviewContent because it's a child of TableOfContents and I believe in React children are rendered before their parents (inside-out)?
I think you need to rethink your component structure. I don't know your entire setup, but it looks like you should probably have a shared parent component pass the message from TableOfContents to InterviewContent:
const InterviewContentMain = Component({
getInitialState() {
return {
inkEnabled: false
}
},
componentDidMount() {
console.log("InterviewContentMain mounted");
},
enableInk() {
this.setState({ inkEnabled: true });
}
render(){
var company = this.props.company;
return (
<div id="interview-content" className="clear-both">
<div className="column-group">
<div className="all-20">
<TableOfContents inkEnabled={this.state.inkEnabled} company={company}/>
</div>
<div className="all-80">
<InterviewContainer enableInk={this.enableInk} company={company}/>
</div>
</div>
</div>
)
}
})
const TableOfContents = Component({
store: Store('/companies'),
componentDidMount() {
console.log("table of contents mounted");
this.props.enableInk();
},
...
const InterviewContent = Component({
enableInk() {
new Ink.UI.Sticky(el, {topElement: "#interview-heading", bottomElement: "#footer"});
},
// willReceiveProps isn't called on first mount, inkEnabled could be true so
componentDidMount() {
if (this.props.inkEnabled) {
this.enableInk();
}
},
componentWillReceiveProps(nextProps) {
if (this.props.inkEnabled === false && nextProps.inkEnabled === true) {
this.enableInk();
}
}
render(){
var company = this.props.company;
return (
<div id="ft-interview-content">
<p className="section-heading bold font-22" id="interview-heading">Interview</p>
<InterviewContentMain company={company}/>
</div>
)
}
})
Then have componentDidMount trigger this.props.enableInk().
Or better yet, why not just put the Ink.UI.Sticky call in componentDidMount of InterviewContent?
I am creating a blog using React and Firebase. I have a component called Blogger that creates blog posts and then saves them in firebase. Now, I am trying to render a list of all of the blog posts that have been saved into firebase. I can't seem to get a list to render.
So far, I have created a parent component called Blogger and a child component called List. I want List to render a list of blog post titles within the Blogger component. I've passed the prop title to List like this
What am I doing wrong?
My stack is webpack + React + React Router + Flux + Firebase
I get this error:
The error message I recieve
This is my parent object in which the list is created:
import AltContainer from 'alt-container';
import React from 'react';
import { Link } from 'react-router';
import List from './List.jsx'
import Firebase from 'firebase'
const rootURL = 'https://incandescent-fire-6143.firebaseio.com/';
export default class Blogger extends React.Component {
constructor(props) {
super(props);
this.firebaseRef = new Firebase(rootURL + 'items/');
this.state = {
title: '',
text: ''
};
this.firebaseRef.on('value', function(snapshot) {
console.log(snapshot.val());
});
}
handleInputChange = () => {
this.setState({
title: this.refs.title.value,
text: this.refs.text.value});
}
handleClick = () => {
this.firebaseRef.push({
title: this.state.title,
text: this.state.text,
done: false
})
this.setState({title: '',
text: ''
});
}
render() {
return (
<div>
<div className="row panel panel-default">
<div className="col-md-8 col-md-offset-2">
<h2>
Create a New Blog Post
</h2>
</div>
</div>
<h2>Blog Title</h2>
<div className="input-group">
<input
ref="title"
value={this.state.title}
onChange = {this.handleInputChange}
type="text"
className="form-control"/>
<span className="input-group-btn">
</span>
</div>
<h2>Blog Entry</h2>
<div className="input-group">
<textarea
ref="text"
value={this.state.text}
onChange = {this.handleInputChange}
type="text"
className="form-control"/>
</div>
<div className="blog-submit input-group-btn">
<button onClick={this.handleClick}
className="btn btn-default" type="button">
Publish Blog Post
</button>
</div>
<List title={this.state.title} />
</div>
);
}
}
This is the child object to which I want to pass the props:
import AltContainer from 'alt-container';
import React from 'react';
import { Link } from 'react-router';
import Blogger from './Blogger'
export default class List extends React.Component {
constructor(props) {
super(props);
console.log(Object.keys(this.props.title));
}
render: () => {
return (
if(this.props.title && Object.keys(this.props.title).length === 0) {
return <h4>enter a blog entry to get started</h4>
} else {
var children = [];
for(var key in this.props.title) {
children.push(
<li>
{title.text}
</li>
)
}
}
);
}
}
The error in your screenshot is quite clear. It's a syntax error.
The following is not legal JavaScript:
function foo () {
return ( if (true) return 'hello )
}
Nesting return statements like this will crash.
The pattern you are looking for is more like this:
function foo () {
if (cond) {
return <List />
}
return <SomethingElse />
}
Additionally the way you are writing render is incorrect. Class functions should just be:
render() {
// return stuff
}
Finally your render method should something like this:
render() {
if (this.props.title && Object.keys(this.props.title).length === 0) {
return <h4>enter a blog entry to get started</h4>
}
return Object.keys(this.props.title).map(key =>
<li>{this.props.title[key]}</li>
)
}
Here is the solution
Blogger.jsx
import AltContainer from 'alt-container';
import React from 'react';
import { Link } from 'react-router';
import List from './List.jsx'
import Firebase from 'firebase'
const rootURL = 'https://incandescent-fire-6143.firebaseio.com/';
export default class Blogger extends React.Component {
constructor(props) {
super(props);
this.firebaseRef = new Firebase(rootURL + 'items/');
this.state = {
title: '',
text: ''
};
this.firebaseRef.on('value', function(snapshot) {
console.log(snapshot.val());
});
}
handleInputChange = () => {
this.setState({
title: this.refs.title.value,
text: this.refs.text.value});
}
handleClick = () => {
this.firebaseRef.push({
title: this.state.title,
text: this.state.text,
done: false
})
this.setState({title: '',
text: ''
});
}
render() {
return (
<div>
<div className="row panel panel-default">
<div className="col-md-8 col-md-offset-2">
<h2>
Create a New Blog Post
</h2>
</div>
</div>
<h2>Blog Title</h2>
<div className="input-group">
<input
ref="title"
value={this.state.title}
onChange = {this.handleInputChange}
type="text"
className="form-control"/>
<span className="input-group-btn">
</span>
</div>
<h2>Blog Entry</h2>
<div className="input-group">
<textarea
ref="text"
value={this.state.text}
onChange = {this.handleInputChange}
type="text"
className="form-control"/>
</div>
<div className="blog-submit input-group-btn">
<button onClick={this.handleClick}
className="btn btn-default" type="button">
Publish Blog Post
</button>
</div>
<List title={this.state.title} />
</div>
);
}
}
List.jsx
import AltContainer from 'alt-container';
import React from 'react';
import { Link } from 'react-router';
import Blogger from './Blogger'
export default class List extends React.Component {
constructor(props) {
super(props);
// console.log(this.props.blog);
}
render() {
console.log(this.props.blog)
// Object.keys(this.props.title[key]).map(key) =>
// <li>{this.props.title}</li>
// )
return (
<div>
<li>{this.props.blog.title}</li>
</div>
)
}
}