#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
.
Вы можете решить проблему двумя способами:
- Объявляя их как функции со стрелками, которые не связываются
this
с помощью записиgetFilteredTrades = () => { ... }
иgetAllTrades = () => { ... }
. - Привяжите
this
ключевое слово функций к объекту класса, написавthis.getFilteredTrades = this.getFilteredTrades.bind(this)
andthis.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 = этот трюк, который был предложен выше