为什么状态仅在变量分配后消失?

时间:2019-01-08 15:07:03

标签: javascript reactjs web react-dom

对于要制作的文件库,我有一个非常简单的设置,其中包含一个主组件和两个子组件。图像预览当然具有向左和向右箭头,可以通过传递,也可以传递回来,该函数创造性地称为“ 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} /> ,并且只有在尝试将其分配给变量进行修改时,它才会出错。

这是可以顺利通过的子组件:

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/BGNqtp7.png

这是调用方法的地方。

this.state["activeFile"]

更多详细信息:https://i.imgur.com/okvE7T3.png

如您所见,数据是存在且可读的,但不可分配。我从未见过这样的事情,并且尝试了无数种诸如#!/bin/bash params="path=/me & you/folder/file.json&&user=Bob" splitParams=(${params//&&/ }) for i in "${!splitParams[@]}" do echo "$i: ${splitParams[i]}" done 之类的解决方案。

这真的让我陷入困境,我先感谢您的帮助!

非专业的Codepen原型进行演示:

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

4 个答案:

答案 0 :(得分:2)

这与React无关,与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;
}

应该可以:)

答案 1 :(得分:0)

您可以对此进行审查。

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

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

答案 2 :(得分:0)

当您要基于先前的值修改状态时,建议不要直接在this.state.[x]函数中使用setState,因为它容易出错。

推荐的方法是使用this.setState(prevState => ({ }))并使用previousState中的变量。

此外,从函数中发送-11可以更轻松地进行处理:

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>

答案 3 :(得分:0)

由于代码被解释为

,您遇到了错误
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})
}