Привязка React-Rails возвращает не функцию - PullRequest
2 голосов
/ 12 апреля 2020

Я работал над своим приложением. И когда я пытался связать свою функцию в вызове jQuery ajax, он всегда говорит: Uncaught TypeError: this.addNewAppointment is not a function

Вот мой полный файл Appointments.jsx:

import React from 'react';
import Appointment from './Appointment';
import AppointmentForm from './AppointmentForm';
import AppointmentsList from './AppointmentsList';

class Appointments extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            appointments: this.props.appointments,
            title: 'Put your event title',
            appointment_time: 'When would this happen?'
        };

        this.handleUserInput = this.handleUserInput.bind(this);
        this.handleFormSubmit = this.handleFormSubmit.bind(this);
        this.addNewAppointment = this.addNewAppointment.bind(this);
    }

    handleUserInput(obj_value){
        this.setState(obj_value);
    }

    handleFormSubmit(){
        let appointment = JSON.stringify({ 
            title: this.state.title, 
            appointment_time: this.state.appointment_time 
        });

        $.ajax({
            url: '/appointments',
            type: "POST",
            data: appointment, 
            contentType: 'application/json',
            success: function(data){
                this.addNewAppointment(data)
            }
        });
    }

    addNewAppointment(appointment){
        let appointments = React.addons.update(this.state.appointments, { $push: [appointment] } );
        this.setState({ appointments: appointments.sort((a, b) => (new Date(a.appointment_time) - new Date(b.appointment_time))
        )})
    }

    render(){
        return(
            <div>
                <AppointmentForm title={this.state.title} 
                    appointment_time={this.state.appointment_time} 
                    onUserInput={this.handleUserInput}
                    onFormSubmit={this.handleFormSubmit}
                />
                <AppointmentsList appointments={this.props.appointments} />
            </div>
        );
    }
}

export default Appointments;

Я звоню своему привязка к конструктору:

this.addNewAppointment = this.addNewAppointment.bind(this);

Это вызов ajax, когда я пытался вызвать функцию addNewAppointment:

$.ajax({
    url: '/appointments',
    type: "POST",
    data: appointment, 
    contentType: 'application/json',
    success: function(data){
        this.addNewAppointment(data)
    }
});

Но когда я пытался добавить новый элемент Я получаю эту ошибку:

Appointments.jsx:38 Uncaught TypeError: this.addNewAppointment is not a function
        at Object.success (Appointments.jsx:38)
        at fire (jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1:3233)
        at Object.fireWith [as resolveWith] (jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1:3363)
        at done (jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1:9841)
        at XMLHttpRequest.callback (jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1:10312)

Есть идеи, что я делаю не так?

1 Ответ

1 голос
/ 12 апреля 2020

Вы связываете метод addNewAppointment, так что каждый раз, когда он вызывается, контекст выполнения (т. Е. Значение this) будет Appointments экземпляром.

Это будет гарантировать, что независимо от того, как вызывается метод, вы сможете получить доступ к this.state.appointments и вызвать this.setState внутри метода addNewAppointment.

Но эта привязка не гарантирует, что каждый раз, когда вы пытаетесь вызвать Метод с this.addNewAppointment, значение this будет экземпляром компонента. В представленном случае, когда вызов $.ajax создает новый контекст выполнения, при вызове:

$.ajax({
    url: '/appointments',
    type: "POST",
    data: appointment, 
    contentType: 'application/json',
    success: function(data){
        this.addNewAppointment(data)
    }
});

контекст выполнения (значение this) не является экземпляром компонента. Чтобы решить эту проблему, вы можете сделать две вещи:

  1. Определить обратный вызов успеха как функцию стрелки, которая наследует родительский контекст выполнения:
$.ajax({
    url: '/appointments',
    type: "POST",
    data: appointment, 
    contentType: 'application/json',
    success: data => {
        this.addNewAppointment(data)
    }
});
Сохраните контекст выполнения, когда вы знаете, что это экземпляр компонента, а затем используйте эту ссылку:
handleFormSubmit() {
    const self = this;
    const appointment = JSON.stringify({ 
        title: this.state.title, 
        appointment_time: this.state.appointment_time 
    });

    $.ajax({
        url: '/appointments',
        type: "POST",
        data: appointment, 
        contentType: 'application/json',
        success: function(data){
            self.addNewAppointment(data)
        }
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...