2

Im working on this app and when I run npm start I keep getting this error "TypeError: render is not a function". Ive tired everything from deleting the dependencies to running npm install. I even update react-router-dom and react-dom several times. Im at a lost here.

Here is the GitHub to the repository https://github.com/Drayz/My-Book-Reads-App.git

Here is the Code:

index.js

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
import "./index.css";

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
); enter code here

App.js:

import React from 'react'
import { Switch,Route } from 'react-router-dom'
import Homepage from './windows/Homepage'
import Search from './windows/Search'
import Provider, {MyContext} from './Provider/'
import './App.css'

class BooksApp extends React.Component {

  render() {
    return (
      <div className="app">
      <Provider>
        <MyContext.Consumer>
            context
          <Switch>
            <Route exact path={"/"} render={ () => (
              <MyContext.Consumer>
                {context => <Homepage {...context} />}
              </MyContext.Consumer>
            )}/>
            <Route exact path={"/search"} render={ () => (
              <MyContext.Consumer>
                {context => <Search {...context} />}
              </MyContext.Consumer>
            )}/>
          </Switch>
        </MyContext.Consumer>
      </Provider>
      </div>
    )
  }
}

export default BooksApp

Provider/index.js:

import React, { Component } from 'react';
export const MyContext = React.createContext();

export default class index extends Component {
  constructor() {
    super();
    this.state ={
      books:[],
      currentlyReading:[],
      wantToRead:[],
      read:[],
      addBooks: books => {
        const currentlyReading = books.filter(book => book.shelf === 'currentlyReading');
        const read = books.filter(book => book.shelf === 'read');
        const wantToRead = books.filter(book => book.shelf ==='wantToRead');
          this.setState({ books, currentlyReading, read, wantToRead });
      },
        moveBook: (book, newShelf, allShelfs) => {
          console.log(newShelf);
          const newBooks = this.state.books.map(allBooks => {
            const foundID = allShelfs[newShelf].find(
              bookID => bookID === allBooks.id
            );
            if (foundID) {
              allBooks.shelf = newShelf;
            }
            return allBooks;
          });
          this.state.addBooks(newBooks);
        }
     };
  }
  render() {
     return (
       <MyContext.Provider value={{...this.state}}>
          {this.props.children}
       </MyContext.Provider>
    )
  }
}

SearchBook.js

import React, {Component} from 'react';
import {Link} from 'react-router-dom'

export default class Searchbooks extends Component {
  render() {
     return (
       <div className="open-search">
         <Link to={'/search'}>
          Add a book
         </Link>
       </div>
    )
  }
}

Bookshelf.js

import React, {Component} from 'react';
import Book from './Book';

export default class Bookshelf extends Component {
  render() {
     return (
       <div className="bookshelf">
        <h2 className="bookshelf-title">{this.props.title}</h2>
        <div className="bookshelf-books">
          <ol className="books-grid">
              {this.props.books &&
                this.props.books.map(book => <Book key={book.id} {...book} moveBook={this.props.moveBook} />)}
          </ol>
        </div>
       </div>
    )
  }
}

Book.js

import React, {Component} from "react";
import {update} from '../BooksAPI'

export default class Book extends Component {
  handleChange = async e => {
    e.presist()
    try {
      const shelf = e.target.value;
      const book = this.props;
      const result = await update(book, shelf);
      this.props.moveBook(book, shelf, result);
    } catch (error) {
      console.log(error)
    }
  };

  render() {
     return (
       <li>
         <div className="book">
           <div className="book-top">
             <div className="book-cover"
             style={{
               width: 128,
               height: 193,
               backgroundImage:`url(${this.props.imageLinks ? this.props.imagesLinks.thumnail : ''})`
              }}
             />
             <div className="book-shelf-changer">
               <select onChange={this.handleChange} value={this.props.shelf}>
                 <option value="move" disabled>Move to...</option>
                 <option value="currentlyReading">Currently Reading</option>
                 <option value="wantToRead">Want to Read</option>
                 <option value="read">Read</option>
                 <option value="none">None</option>
               </select>
             </div>
           </div>
           <div className="book-title">{this.props.title}</div>
           <div className="book-authors">{this.props.authors ? this.props.author[0] : 'No Author'}</div>
         </div>
       </li>
     )
  }
}

Local_Host_Error, Local_Host_Error, Local_Host_Error

1 Answer 1

1

In App.js your consumer just says "context". I think what you meant was for that to be the variable that holds the data that comes from the provider. Right now it's just being read as a string and the render function freaks out because... well the logging isn't very good. In short when the component goes to render it hits a whole bunch of undefined and freaks out.

To fix this use:

{ context => {Your switch statement }}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.