React не может прочитать свойство ‘setState’ неопределенного значения в if-block

#javascript #reactjs #this #webstorm #setstate

#javascript #reactjs #это #webstorm #setstate

Вопрос:

Я создаю свое первое интерфейсное приложение ReactJS и сталкиваюсь с проблемой. Когда я пытаюсь вызвать свою функцию setState (или любую другую функцию, если на то пошло) с помощью this . перед ним внутри блока if я получаю сообщение об ошибке.

Необработанное отклонение (TypeError): не удается прочитать свойство ‘setState’ неопределенного значения

Когда я вызываю функции внутри моего didComponentMount (), все в порядке, поэтому я думаю, что проблема в блоке if. Я пробовал несколько решений по разным вопросам, но ни в одном из них нет блока if, поэтому он не работает для меня.

Функция, которая выдает ошибку:

 getFilteredTrades() {
        if(document.getElementById("switch").checked){
            fetch("http://localhost:8080/trades/filter?plaform=NintendoSwitch").then(rse => rse.json()).then(
                result => {
                    this.setState({trades: result});
                }
            )
        } else if (document.getElementById("playstation").checked) {
            fetch("http://localhost:8080/trades/filter?platform=PlayStation").then(rse => rse.json()).then(
                result => {
                    this.setState({trades: result});
                }
            )
        } else if (document.getElementById("xbox").checked) {
            fetch("http://localhost:8080/trades/filter?platform=XBox").then(rse => rse.json()).then(
                result => {
                    this.setState({trades: result});
                }
            )
        } else if (document.getElementById("pc").checked) {
            fetch("http://localhost:8080/trades/filter?platform=PC").then(rse => rse.json()).then(
                result => {
                    this.setState({trades: result});
                }
            )
        } else {
            alert("No filter is selected, so all trades will be displayed.")
            this.getAllTrades();
        }
    }
  

Как setState, так и getAllTrades будут выдавать здесь ошибки.

getAllTrades():

 getAllTrades() {
        fetch("http://localhost:8080/trades/all").then(rse => rse.json()).then(
            result => {
                this.setState({trades: result});
            }
        )
    }
  

конструктор:

 constructor(props){
        super(props);

        this.state = {
            trades: []
        }
    }

  

didComponentMount, где getAllTrades РАБОТАЕТ:

 componentDidMount() {
        this.getAllTrades();
    }
  

Кто-нибудь знает решение этой проблемы? Заранее спасибо.

Ответ №1:

В ваших getFilteredTrades getAllTrades функциях и this ссылается на сами функции, а не на объект, и у этих функций нет члена setState .

Вы можете решить проблему двумя способами:

  1. Объявляя их как функции со стрелками, которые не связываются this с помощью записи getFilteredTrades = () => { ... } и getAllTrades = () => { ... } .
  2. Привяжите this ключевое слово функций к объекту класса, написав this.getFilteredTrades = this.getFilteredTrades.bind(this) and this.getAllTrades = this.getAllTrades.bind(this) в вашем конструкторе.

Комментарии:

1. Оба эти решения приводят к новой ошибке в моей функции рендеринга, в которой говорится, что this.state.trades.map() не является функцией.

2. Ну, тогда вы ожидаете this.state.trades , что это будет массив, но это не так. Проверьте, что вы получаете от своих fetch функций.

3. @Peter_Lehnhardt Когда я регистрирую его на своей консоли, насколько мне известно, он показывает массив…

4. Можете ли вы позвонить console.log(this.state.trades, this.state.trades instanceof Array) прямо перед вызовом this.state.trades.map( ... ) ?

5. Мой плохой, это вообще не было проблемой. Я неправильно ввел «platform» в первом URL-адресе выборки, и именно поэтому он не вернул массив. Оказывается, ваше решение работает, спасибо!

Ответ №2:

Кажется, в какой-то момент вы теряете контекст. Попробуйте связать свои методы или сделать их функциями со стрелками:

 getAllTrades=()=>{...}
  

Если это не поможет, попробуйте объединить его с self = этот трюк, который был предложен выше