Почему State исчезает только при присваивании переменной? - PullRequest
0 голосов
/ 08 января 2019

У меня есть очень простая настройка для галереи файлов, которую я делаю, которая включает главный компонент и два подкомпонента. Предварительный просмотр изображения, разумеется, имеет стрелки влево и вправо, которые передаются и передаются обратно, функция, творчески называемая «clickHandler», которая просто обновляет состояние просматриваемого файла.

Однако при вызове события clickHandler и создании временной переменной для изменения и отправки обратно в состояние приложение вылетает при ошибке _this.state.activeFile is not a function.

Странная часть этого, однако, в том, что состояние полностью читаемо. Он может console.log() отлично работать, и только при попытке присвоить его переменной для изменения выдает ошибку.

Вот подкомпонент, который проходит нормально:

<FileView 
    file={this.props.media[this.state.activeFile]} 
    handler={this.clickHandler} 
    active={this.state.activeFile} 
    max={this.props.media.length}
/>

Подробнее: https://i.imgur.com/BGNqtp7.png

А вот где метод вызывается.

state={
    activeFile: 2
}
clickHandler=(direction)=>{
    console.log (this.state); // > Object { activeFile: 2 }
    console.log (this.state.activeFile); // > 2
    let temp =  (this.state.activeFile) // ? TypeError: _this.state.activeFile is not a function

    // vvv Likely unrelated, but posted also for context
    // evals left or right to plus or minus
    (direction==="prev"?temp-=1:(direction==="next"?temp+=1:""))
    this.setState({activeFile: temp})
}

Подробнее: https://i.imgur.com/okvE7T3.png

Как видите, данные присутствуют и читаются, но не могут быть назначены. Я никогда не видел ничего подобного, и попробовал множество решений, таких как this.state["activeFile"], но безрезультатно.

Этот действительно бросает меня в тупик, заранее благодарен за любую помощь!

Контент-непрофессиональный прототип Codepen для демонстрации:

https://codepen.io/Jop/pen/vvJrqv

Ответы [ 4 ]

0 голосов
/ 08 января 2019

Вы получаете ошибку, потому что код интерпретируется как

let temp = (this.state.activeFile)(direction==="prev"?temp-=1:(direction==="next"?temp+=1:""))

Поэтому добавьте точку с запятой перед ternary функцией или используйте оператор else if. Оба должны работать

 clickHandler=(supdawg)=>{
    let temp = (this.state.activeFile);
    (supdawg==="left" ? temp-=1 : (supdawg==="right") ? temp+= 1 : "");
    this.setState({activeFile: temp});
}

или

clickHandler=(supdawg)=>{
    let temp = (this.state.activeFile)
    if (supdawg === "left") { temp -=1}
    else if (supdawg === "right") { temp+=1}
    else {temp = ""}
    this.setState({activeFile: temp})
}
0 голосов
/ 08 января 2019

Если вы хотите изменить свое состояние на основе предыдущего значения, не рекомендуется использовать this.state.[x] непосредственно в функции setState, так как это подвержено ошибкам.

Рекомендуется использовать this.setState(prevState => ({ })) и использовать переменные из previousState.

Кроме того, отправка -1 и 1 из ваших функций упрощает обработку:

MediaViewer:

clickHandler = offset => event => {
    this.setState(prevState => ({ activeFile: prevState.activeFile + offset }))
}

ActiveFile:

<div className="info-view_paging">
    {props.active < 1 ? <div></div> : <div className="info_pager" onClick={props.handler(-1)}><button>previous</button></div>}
    <div></div>
    {props.max > props.active ? <div className="info_pager" onClick={props.handler(1)}><button>next</button></div> : <div></div>}
</div>
0 голосов
/ 08 января 2019

Это не что-то с реакцией, это что-то с помощью JavaScript! Код с ошибкой вы выложили так:

let temp =  (this.state.activeFile) // ? TypeError: _this.state.activeFile is not a function

// vvv Likely unrelated, but posted also for context
// evals left or right to plus or minus
(direction==="prev"?temp-=1:(direction==="next"?temp+=1:""))

Но из-за того, как работает синтаксис, javascript видит это как

let temp = (this.state.activeFile)(direction==="prev"?temp-=1:(direction==="next"?temp+=1:""))

И вы видите, как он думает, что ожидает функцию сейчас;) Если переписать его на

let temp =  this.state.activeFile;

if (direction === "prev") {
  temp -= 1;
} else if (direction === "next") {
  temp += 1;
}

Должно работать:)

0 голосов
/ 08 января 2019

Вы можете оставить отзыв.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

<FileView handler={this.clickHandler.bind(this)} />
...