Невозможно прочитать свойство setState со значением null при нажатии кнопки

Я работаю над приложением responsejs, и у меня возникла проблема с доступом к состоянию внутри функции updateVert. Когда я нажимаю кнопку «play», вызывается actionButton, а изнутри actionButton вызывается updateVert.

Ниже мой фрагмент кода

updateVert() {

        console.info("inside upver")
        if (play) {
            cancelAnimationFrame(this.updateVert);
            return;
        }

       this.setState({xPos: this.state.xPos + 1}, ()=>{
           if (this.state.xPos >= w) {
               // stop animation...
               this.setState({xPos:0, playing:false});
           }
           ctx.clearRect(0, 0, w, h);

           // draw new one...
           ctx.beginPath();
           ctx.strokeStyle = "#19f";
           ctx.lineWidth = 2;
           ctx.moveTo(this.state.xPos, 0);
           ctx.lineTo(this.state.xPos, 200);
           ctx.stroke();

           if (this.state.playing) {
               console.info("yes true")
               requestAnimationFrame(this.updateVert)
           };
       })
        // reset rectangle content to erase previous line...
    }

    actionButton(){
        if (this.state.playing) {
            // pause...
            this.setState({playing:false},()=>{
                console.info(this.state.playing)
            })
        }
        else {
            this.setState({playing:!this.state.playing},()=>{
                console.info(this.state.playing)
                this.updateVert();
            })

        }
    }

  render() {
        return (
            <div>
                <div className = "App">
                    <canvas id = "DemoCanvas" width = "500" height = "200"></canvas>
                </div>
                <button onClick = {this.actionButton.bind(this)}>{this.state.playing ? "Stop":"Play"}</button>
            </div>


    );
  }

Когда я нажимаю кнопку (воспроизведение / пауза), я получаю сообщение об ошибке

TypeError: Cannot read property 'setState' of null
updateVert
src/App.js:45
  42 |      return;
  43 |  }
  44 | 
> 45 | this.setState({xPos: this.state.xPos + 1}, ()=>{
  46 |     if (this.state.xPos >= w) {
  47 |         // stop animation...
  48 |         this.setState({xPos:0, playing:false}); 

Я правильно указал функцию updateVert. Что я делаю не так?

Поведение ключевого слова "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
159
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Попробуйте привязать контекст конкретно в requestAnimationFrame

requestAnimationFrame(this.updateVert.bind(this))

Надеюсь это поможет

requestAnimationFrame, что это?

Bhojendra Rauniyar 24.08.2018 09:47

Я знаю это, но что это используется для привязки? Любая ссылка? Для меня это было бы новой находкой :)

Bhojendra Rauniyar 24.08.2018 09:49

Мое предположение заключалось в том, что сама функция не была объявлена ​​с использованием нотации стрелочной функции, поэтому при вызове внутри requestAnimationFrame она теряла свой контекст. Как сказал Аншул, вы можете просто указать функцию как стрелочную функцию, или вы можете связать контекст в ней специально

Azamat Zorkanov 24.08.2018 09:55

Мне любопытно узнать, как requestAnimationFrame используется для привязки контекста. К вашему сведению, я не голосовал против.

Bhojendra Rauniyar 24.08.2018 09:57

К вашему сведению, я не голосовал против. - лол, мне плевать :). Как я уже сказал, это было просто мое предложение, нужно это проверить

Azamat Zorkanov 24.08.2018 09:58
codeandbox.io/s/rwm2lyxlm Здесь я создал песочницу, которая доказывает, что мой ответ правильный. Для надежности вы можете привязать это к функции обновления в setTimeout: setTimeout (this.update.bind (this), 1000); FIY, действительно не имеет значения, setTimeout или requestAnimationFrame - принцип остается прежним. Надеюсь, я удовлетворил ваше любопытство: D
Azamat Zorkanov 24.08.2018 10:10

Я как-то согласен. Но где вы нашли использование requestAnimationFrame для привязки контекста?

Bhojendra Rauniyar 24.08.2018 10:41

Вам не хватает привязки контекста this:

В ловушке actionButton(){ вы вызываете this.updateVert(), который не привязан к this. Таким образом свяжите его внутри конструктора:

this.updateVert.bind(this)
Ответ принят как подходящий

Он не получает правильный контекст this. Не нужно писать дополнительный код для привязки. Вам нужно изменить

updateVert() { .... }

к

updateVert = () => {.... }

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