import React from 'react';
import './App.css';
import SearchBar from '../SearchBar/SearchBar';
import SearchResult from '../SearchResult/SearchResult';
import PlayList from '../PlayList/PlayList';
class App extends React.Component {
constructor(props) {
super(props)
this.state = {searchResult: [{name: 'The Real Slim Shady', album: 'Marshal Matters LP', artist: 'Eminem', id: 1},
{name: 'Shizzle', album: 'My Dizzle', artist: 'Snoop Dogg', id: 1}]
}
}
render() {
return (
<div>
<h1>Ja<span className="highlight">mmm</span>ing</h1>
<div className="App">
<SearchBar />
<div className="App-playlist">
<SearchResult searchResult={this.state.searchResult} />
<PlayList />
</div>
</div>
</div>
);
}
}
export default App;
--------------------------------------------------------------------------
import React from 'react';
import './SearchResult.css';
import TrackList from '../TrackList/TrackList'
class SearchResult extends React.Component {
render() {
return (
<div className="SearchResults">
<h2>Results</h2>
<TrackList tracks={this.props.searchResult} />
</div>
)
}
}
export default SearchResult;
-------------------------------------------------------------------
import React from 'react';
import './TrackList.css';
import Track from '../Track/Track';
class TrackList extends React.Component {
render() {
return (
<div className="TrackList">
{this.props.tracks.map(track => {
return <Track key={track.id} track={track} />
})}
</div>
)
}
}
export default TrackList;
So I'm passing the state to a child element and than I'm trying to render it as props and I'm getting an error.
Error: Objects are not valid as a React child (found: object with keys {name, album, artist, id}). If you meant to render a collection of children, use an array instead.
I'm lost and there are couple similar problems on Google but I can't work it out. Pls Help.
Related
Very Simple code , I'hv checked react spelling, ReactDom imported, Please guide me about the error. I am new to the codding world.
import React, { Component } from "react";
import "./App.css";
import { Cardlist } from "./components/cardlist/cardlist.component.jsx";
class App extends Component {
constructor() {
super();
this.state = {
string: "Hello before",
};
}
render() {
return (
<div className="App">
<p>{this.state.string}</p>
<button onClick={() => this.setState({ string: "After text" })}>
Change text
</button>
<Cardlist name="this was prop" />
</div>
);
}
}
export default App;
Cardlist component
import react from "react";
export const Cardlist = (props) => {
console.log(props);
return <div>COngratulations</div>;
};
Try changing that react to React on first line on CardList ?
I am writing a react application that outputs a list of books (image, title, category, and description).
My search bar and booklist are sibling components and the search bar will pass data to the booklist.
when clicking the search button, only "Sample Category" shows up but not anything else. There is no problem accessing the API and the data is not null.
Here is a sample API output: https://www.googleapis.com/books/v1/volumes?q=lordoftherings
My code is the following:
// App
import React, { Component } from 'react';
import Axios from 'axios';
import './App.css';
import SearchBar from './SearchBar';
import BookList from './BookList';
class App extends Component {
constructor(props) {
super(props);
this.state = {
books: []
};
this.search = this.search.bind(this);
}
search(title) {
const promise = Axios.get('https://www.googleapis.com/books/v1/volumes?q=' + title);
promise.then((response) => {
const books = response.data.items;
this.setState({ books: books });
console.log(this.state.books);
})
};
render() {
return (
<div className="App">
<SearchBar searchBooks = {this.search}/>
<BookList booklist = {this.state.books}/>
</div>
);
}
}
export default App;
// Search Bar
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class SearchBar extends Component {
constructor(props) {
super(props);
this.state = { titleToSearch: 'harry potter' }
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(e) {
this.setState({ titleToSearch: e.target.value });
};
render() {
return (
<form>
<input
type="text"
name="booksInput"
placeholder="Enter book title"
value={this.state.titleToSearch}
onChange={this.handleInputChange}
/>
<button type="button" onClick={() => this.props.searchBooks(this.state.titleToSearch)}>Search</button>
</form>
);
}
}
export default SearchBar;
// BookList
import React, { Component } from 'react';
class BookList extends Component {
render() {
const books = this.props.booklist;
return (
<div className="table">
{books.map((book) => {
console.log(book.id);
return (
<div className="box" key={book.id}>
<div className="img"><img src="assets/default-placeholder.jpg" alt="" /></div>
<div className="title">{book.title}</div>
<div className="category">Sample Category</div>
<div className="description">{book.description}</div>
</div>
);
})}
</div>
);
}
}
export default BookList;
In the sample code you provided, you're not actually dynamically outputting categories.
You've hard coded 'Sample category' in there.
book.category
...is not actually in the dataset.
There are categories which seem to be available under:
<div className="category">{book.volumeInfo.categories[0]}</div>
although you'll want to check if the array has length, and probably map or join each item in array to string.
just to be clear: the issue with your other fields is also that they're children of "volumeInfo"
I am getting an "TypeError: this is undefined" error even after I am binding this to the function in the constructor. I have also tried to use handleChange={this.handlChange.bind(this)} instead of this.handleChange = this.handleChange.bind(this) but it doesn't work. I am watching React tutorial and I wrote the same code as the tutor did, the code is working fine in his IDE but is showing error in mine.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
App.js
import React from 'react';
import './css/App.css';
import Header from "./components/Header"
import MainContent from "./components/MainContent"
import Footer from "./components/Footer"
class App extends React.Component {
render(){
return (
<div>
<Header />
<MainContent />
<Footer />
</div>
)
}
}
export default App;
MainContent.js
import React, {Component} from "react"
import ListItem from "./ListItem"
import tasks from "./tasks"
class MainContent extends Component
{
constructor()
{
super()
this.state =
{
tasks: tasks
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(completed)
{
alert(completed)
}
render()
{
const taskComponents = this.state.tasks.map(function(data)
{
return <ListItem key={data.id} task={data.task} completed={data.completed} handleChange={this.handleChange} />
})
return (
<div>
{taskComponents}
</div>
)
}
}
ListItem.js
import React from "react"
let i=1;
class ListItem extends React.Component
{
render()
{
return (
<div>
<p style={{color : i%2 ? "black" : "orange"}}>
<input type="checkbox" checked={this.props.completed}
onChange={function(){
this.props.handleChange(this.props.completed)
}}>
</input> Task {i++} : <b>{this.props.task}</b>
</p>
</div>
)
}
}
export default ListItem
I'm trying to change the state of one component from another component and my state is not updating, I'm sending back the prop i want to update in my app component but this.setState doesnt work
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import Header from './components/Header';
class App extends Component{
constructor(){
super();
this.state = {
homeLink: "Home"
}
}
onChangeLink(newLink){
this.setState({
homeLink: newLink
});
}
render(){
var user = {
name: "sadf"
}
return(
<div className="container">
<div className="row">
<Header changeLink={this.onChangeLink.bind(this)}/>
</div>
</div>
);
}
}
ReactDOM.render(
<App />,document.getElementById('app')
And here is my header component
import React, {Component} from 'react';
class Header extends Component{
constructor(){
super();
this.state = {
homeLink: 'New Link'
}
}
onChangeLink(){
this.props.changeLink(this.state.homeLink);
}
render(){
return(
<nav className="navbar navbar-default">
<button onClick={this.onChangeLink.bind(this)}>Change Link</button>
</nav>
)
}
}
export default Header
Try something like this:
let newPropValues = {
root: event.target.value
};
this.setState(Object.assign({}, this.state, newPropValues));
I have a TodoList component which is a child of the App component. I wish to change the state of the App component's todos list. I am attempting to pass a toggleComplete function from the TodoList component to the Todo component so at onClick event it would fire and work its way up to the App component so I could update the state.
I get a "Uncaught TypeError: Cannot read property 'toggleComplete' of undefined" in the TodoList.js
~/src/component/Todo.js
import React, {PropTypes} from 'react';
export default class Todo extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<li className={this.props.todo.done ? 'completed' : 'view'}>
<div className="view">
<input onClick={this.props.toggleComplete(this.props.id)} className="toggle" type="checkbox" checked={this.props.todo.done} />
<label>{this.props.id}: {this.props.todo.title}</label>
<button className="destroy"></button>
</div>
</li>
);
}
}
~/src/component/TodoList.js
import React, {PropTypes} from 'react';
import Todo from './Todo'
export default class TodoList extends React.Component {
constructor(props) {
super(props);
}
toggleComplete(todoID){
console.log('hit toggleComplete TodoList');
}
render() {
return (
<section className="main">
<ul className="todo-list">
{this.props.todos.map(function(todo, index){
return <Todo todo={todo} toggleComplete={this.toggleComplete} id={index + 1} key={index+1}/>;
})}
</ul>
</section>
);
}
}
~/src/App.js
import React, { Component } from 'react';
import Header from './component/Header'
import TodoList from './component/TodoList'
import TodoFooter from './component/TodoFooter'
import Footer from './component/Footer'
export default class App extends Component {
constructor(){
super();
this.state = {
todos: [
{title: 'Taste JavaScript', done: true},
{title: 'Buy Unicorn', done: false},
{title: 'eat all day', done: false},
{title: 'sleep all night', done: true}
]
}
}
render() {
return (
<div>
<section className="todoapp">
<Header />
<TodoList todos={this.state.todos} />
<TodoFooter />
</section>
<Footer />
</div>
);
}
}
Your problem seems to occur before the function makes it to your child component, as the error is coming from your parent component. Your map function does not have access to the correct this, so it is treated as undefined -- try this instead:
{this.props.todos.map(function(todo, index){
return <Todo todo={todo} toggleComplete={this.toggleComplete} id={index + 1} key={index+1}/>;
}, this)} // use the optional "this" argument to the map function
And here's a fiddle to play with showing a simple example of parents rendering their many children with the same reference to the parent's scope: https://jsfiddle.net/v5wd6Lrg/1/
The above answer can also be done using arrow function without binding
{this.props.todos.map((todo, index) => {
return <Todo todo={todo} toggleComplete={this.toggleComplete} id={index + 1} key={index+1}/>;
});