React - Uncaught ReferenceError: добавление не определено

Так что я новичок в React (и JS) в целом. Обычно код с Java или C#, и я еще не привык к синтаксису. Мне удалось сделать простой калькулятор с помощью React и я хочу добавить функциональность, но всякий раз, когда я пытаюсь, я получаю сообщение об ошибке, в котором говорится, что мой метод не определен.

В основном функция используется для получения реквизита из моего компонента Button и добавления его в значение компонента Screen.

class Button extends React.Component {
    constructor(props) {
        super(props)
    }

    add(button) {
        let value = button.value
        let text = document.getElementByID('screenInput').value
        if (value == '=') {
            document.getElementById('screenInput').innerHTML = eval(text).toString();
        } else if (value == 'C') {
            document.getElementById('screenInput').innerHTML = '0':
        } else if (value == '+/-' && text != '0') {
            document.getElementById('screenInput').innerHTML = `` - (${ text })``;
        } else if (value == '\d' || (text.slice(-1) != value && text != '0')) {
            document.getElementById('screenInput').innerHTML = text.append(value);
        }
    }

    render() {
        return (
            <button type='button' value = {this.props.value} onClick = {() => add(this)}> {this.props.value}</button >
        )
    }
}

https://jsfiddle.net/q7yakt1v/22/`

add не является глобальным в вашем коде

AlexOwl 13.03.2019 17:14
Поведение ключевого слова "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
1
539
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Таким образом, причина, по которой вы не можете просто ссылаться на добавление, заключается в том, что он неразрывно связан с экземпляром вашего класса Button. Так что, если вы хотите назвать это, вам придется сделать this.add(this).

Проблема, с которой вы столкнетесь дальше, заключается в том, что this, который вы передаете add, является не элементом кнопки, а ссылкой на экземпляр класса.

Я думаю, я должен также добавить, что вы не хотите изменять DOM непосредственно вне React, потому что React внутренне отслеживает изменения. Вы должны предпочесть использовать состояние/контекст для применения изменений к вещам, выходящим за пределы непосредственной области действия вашего компонента.

class Button extends React.Component {
  constructor(props) {
    super(props);
  }

  add() {
    let value = this.value;
    let text = document.getElementByID("screenInput").value;
    if (value == " = ") {
      document.getElementById("screenInput").innerHTML = eval(text).toString();
    } else if (value == "C") {
      document.getElementById("screenInput").innerHTML = "0";
    } else if (value == "+/-" && text != "0") {
      document.getElementById("screenInput").innerHTML = `-(${text})`;
    } else if (value == "d" || (text.slice(-1) != value && text != "0")) {
      document.getElementById("screenInput").innerHTML = text.append(value);
    }
  }

  render() {
    return (
      <button type = "button" value = {this.props.value} onClick = {() => this.add()}>
        {this.props.value}
      </button>
    );
  }
}
  1. У конструктора нет начального состояния, оно нам не нужно.
  2. Автоматическая привязка вашей функции.
add = (button) => {
   let value = this.buttonRef.value;
   // rest of your code
}
  1. Измените визуализацию следующим образом:
render() {
    return (
      <button ref = {(button) => { this.buttonRef = button; }} type = "button" value = {this.props.value} onClick = {() => this.add()}>
        {this.props.value}
      </button>
    );
  }
  1. Я также предлагаю избегать прямых ссылок на документ с помощью document.getElementById в реакции. Вместо этого управляйте переменной состояния.
Ответ принят как подходящий

Как указано в нескольких других ответах, ключевой проблемой вашего кода является onClick = {() => add(this)}. Но я думаю, что это из-за непонимания того, как состояние обрабатывается в React.

У меня есть поднял государство значения экрана в компоненте <Calculator />. Таким образом, мы передаем состояние в компонент <Screen />, чтобы отобразить его, и можем манипулировать им из компонента <Buttons />, не вызывая DOM напрямую (как указал @Avanthika в своем ответе).

class Calculator extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            value: '0'
        }

        this.handleButtonClick = this.handleButtonClick.bind(this)
    }

    handleButtonClick(value) {
        const { value: currentValue } = this.state;
        let newValue;

        if (value == '=') {
            newValue = eval(currentValue).toString();
        } else if (value == 'C') {
            newValue = 0;
        } else if (value == '+/-' && currentValue != '0') {
            newValue = `-(${text})`;
        } else if (currentValue === '0') {
            newValue = value;
        } else {
            newValue = currentValue.concat(value);
        }

        this.setState({ value: newValue });
    }

    render() {
        const { value } = this.state;
        return (
            <div id = "body">
                <Screen value = {value} />
                <Buttons onButtonClick = {this.handleButtonClick} />
            </div>
        )
    }
}

....

const Button = ({ value, onClick }) => (
    <button type = "button" onClick = {() => onClick(value)}>
        {value}
    </button>
)

Я переименовал вашу функцию add и изменил ее поведение. Вместо того, чтобы получать/обновлять значения в DOM, он использует состояние в компоненте <Calculator />.

Вы можете увидеть рабочий код здесь: https://jsfiddle.net/zvxpkq46/

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