TypeError: this.props.AddNewHero не является функцией

Я знаю, что такой вопрос часто публиковался в StackOverFlow, но в моем коде я не смог найти ошибку, почему мой код не работает.

Я пытаюсь создать нового героя в моем компоненте AddHero.js (это дочерний компонент) и обновить этот новый герой до состояния в App.js (родительский компонент). Однако я получаю сообщение об ошибке, показывающее, что TypeError: this.props.AddNewHero не является функцией

Вот мой код:

AddHero.js

import React, { Component } from 'react';

class AddHero extends Component {

    constructor(props) {
        super(props);

        this.onSave = this.onSave.bind(this);

        this.state = {
            Id: 0, Name: "", Dob: new Date(), Stocked: true, Price: 0
        };  
    }

    onNameChange(e) {
        this.setState({
            Name: e.target.value
        });
    }

    onDobChange(e) {
        this.setState({
            Dob: e.target.value
        });
    }

    onStockedChange(e) {
        this.setState({
            Stocked : e.target.value
        });
    }

    onPriceChange(e) {
        this.setState({
            Price : e.target.value
        });
    }

    onSave(e){
        e.preventDefault();

        const newHero = {           
            Name: this.state.Name,
            Dob: this.state.Dob,
            Stocked: this.state.Stocked,
            Price: this.state.Price
          };

        this.props.AddNewHero(newHero); //The error is here
    }

    render() {
        return (
            <div>
                <h1>Add hero</h1>
                <form>
                    <div className = "form-group">
                        <label>Name </label>
                        <input type = "text" onChange = {this.onNameChange.bind(this)}></input>
                    </div>
                    <div className = "form-group">
                        <label>Dob </label>
                        <input type = "date" onChange = {this.onDobChange.bind(this)} defaultValue = {new Date().toISOString().substr(0, 10)}></input>
                    </div>
                    <div className = "form-group">
                        <label>Stocked </label>
                        <input type = "checkbox" onChange = {this.onStockedChange.bind(this)} ></input>
                    </div>
                    <div className = "form-group">
                        <label>Price </label>
                        <input type = "text" onChange = {this.onPriceChange.bind(this)}></input>
                    </div>
                    <button onClick = {this.onSave}>Save</button>
                </form>
            </div>
        );
    }
}

export default AddHero;

App.js

import React, { Component } from 'react';
import { Link, BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import AllHeroes from './components/Hero/AllHeroes';
import AddHero from './components/Hero/AddHero';
import EditHero from './components/Hero/EditHero';


class App extends Component {

  constructor(props) {
    super(props);
  }

  state = {
    Heroes: [
      { Id: 1, Name: "hero1", Dob: new Date("1-1-2017"), Stocked: true, Price: 1.50 },
      { Id: 2, Name: "hero2", Dob: new Date("5-31-2018"), Stocked: false, Price: 2.50 },
      { Id: 3, Name: "hero3", Dob: new Date("2019"), Stocked: true, Price: 3.50 },
      { Id: 4, Name: "hero4", Dob: new Date("4-20-2010"), Stocked: false, Price: 4.50 },
      { Id: 5, Name: "hero5", Dob: new Date("12-31-2018"), Stocked: true, Price: 5.50 },
    ]
  }

  GetAllHeroes() {
    return this.state.Heroes;
  }

  AddNewHero(newHero) {
    const id = this.state.Heroes.length + 1;
    newHero.Id = id;

    this.setState({
      Heroes: [...this.state.Heroes, newHero]
    });
  }

  render() {
    return (
      <Router>
        <div className = "container">

          <Link to = {'/'}>Home </Link><br />
          <Link to = {'/AllHeroes'}>All Heroes </Link><br />
          <Link to = {'/Add'}>Add </Link><br />

          <Switch>
            <Route path='/AllHeroes' component = {AllHeroes} />
            <Route path='/Add' component = {AddHero} AddNewHero = {this.AddNewHero} />
            <Route path='/Edit/:id' component = {EditHero} />
          </Switch>
        </div>
      </Router >
    );
  }
}

export default App;

Заранее благодарю.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
384
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не можете передавать реквизит с таким Route, вы должны использовать render для этой цели.

<Route
  path = "/Add"
  render = {(props) => <AddHero {...props} AddNewHero = {this.AddNewHero} />}
/>

Проблема в том, что вы используете react-router и рассчитываете на него для детализации реквизита, а этого не происходит. Вы должны попытаться передать обернутый компонент вместо исходного в App.js. Следующее должно работать:

<Route path='/Add' component = {() => <AddHero AddNewHero = {this.AddNewHero} />}

Другие вопросы по теме