简体   繁体   中英

React Router: TypeError: render is not a function

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

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 }}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM