繁体   English   中英

this.setState不是函数React

[英]this.setState is not a function React

我知道这种情况有很多答案,涉及使用绑定或箭头功能,但是我的情况有些不同。 基本上,我想用EventListener创建一个div元素,用我单击的特定子元素的索引值更新状态setIndex值。此过程的回调函数是onModal

如果我对onModal使用箭头功能,则'this'关键字将转移到类中,而不是单个元素,因此我将无法访问单个元素的索引。

如果我使用普通功能(如下面的代码所示),则this.setState会转移到各个元素上,并且会出现setState错误

class AddRecipe extends Component{
  constructor() {
    super();
    this.state={
      name:[],
      setIndex:0,
    }
  }

  onLoad() {

    var recipe = document.querySelector(".recipe")

    const name = data.forEach((d,index) => {
      var recipecard = document.createElement("div")
      recipecard.setAttribute("class","recipecard")
      recipecard.setAttribute("key",index)
      recipe.setAttribute("key",0)
      var h1 = document.createElement("h1")
      h1.setAttribute("id","keyhold")
      h1.appendChild(document.createTextNode(data[index].name))
      console.log(h1);
      recipecard.appendChild(h1)
      recipecard.addEventListener("click",this.onModal)
      recipe.appendChild(recipecard)
    })
  }

  componentDidMount() {
    this.onLoad()
  }

  onModal() {
    var index = this.getAttribute("key")
    var recipe = document.querySelector(".recipe")
    recipe.setAttribute("key",index)
    var modal = document.getElementById('MyModal')
    var btn = document.getElementById('myBtn')
    var modal = document.getElementById('myModal');
    var btn = document.getElementById("myBtn");
    modal.style.display = "block";

    this.setState({setIndex:index}).bind(this)

  }

  onClose() {
    var modal = document.getElementById('myModal');
    var span = document.getElementsByClassName("close")[0]
    modal.style.display= "none"
  }

  render() {
    return (
      <div>
        <div id="myModal" class="modal">
          <div class="modal-content">
            <span onClick={this.onClose.bind(this)} class="close">&times;</span>
            <ModalWindow datas= {data} index={this.state.setIndex} />
          </div>
        </div>
        <div className ="recipe">
        </div>
      </div>
    );
  }
}

export default AddRecipe

错误可能出在recipecard.addEventListener("click",this.onModal)您需要向this.onModal调用添加绑定。

我认为无需在setState上使用bind方法。

index参数传递给事件处理程序并进行相应处理。

另外,由于只希望元素上下文用于检索index ,因此可以使用函数currying将index发送到onModal方法。 这样,您不再需要依赖元素的上下文。

如果您的React项目支持类实例方法的箭头功能,那么您可以尝试传递如下参数。

class AddRecipe extends Component{
  ...
  onLoad() {
    var recipe = document.querySelector(".recipe")
    const name = data.forEach((d,index) => {
      ...
      recipecard.addEventListener("click",this.onModal(index))             
      recipe.appendChild(recipecard)
    })
  }

  onModal = (index) => (event) => {
    ...    
    this.setState({ setIndex:index })    
  }
  ...
}

export default AddRecipe

要么

您甚至可以尝试使用React Docs中记录的方式来避免任何混乱https://reactjs.org/docs/handling-events.html#passing-arguments-to-event-handlers

class AddRecipe extends Component{
  ...        
  onLoad() {    
    var recipe = document.querySelector(".recipe")    
    const name = data.forEach((d,index) => {
      ...
      recipecard.addEventListener("click",(event) => this.onModal(index))             
      recipe.appendChild(recipecard)
    })
  }

  onModal = (index) => {
    ...    
    this.setState({ setIndex:index })    
  }
  ...
}

export default AddRecipe

查看本文,了解将参数发送到事件处理程序的多种方法

https://medium.freecodecamp.org/reactjs-pass-parameters-to-event-handlers-ca1f5c422b9

recipecard.addEventListener(“ click”,this.onModal.bind(this))onModal必须绑定,我不确定这是否可以在不绑定的情况下工作

 componentDidMount() {
    this.onLoad()
 }

在构造函数中添加代码行

this.onLoad = this.onLoad.bind(this)

bind将第一个参数附加为您要在其上进行绑定的函数的上下文(即“ this”),并使用新上下文返回一个新函数。

this.setState({...})是一个函数调用,因此无法绑定任何此函数。 您需要这样的东西:

onLoad(){

  var recipe = document.querySelector(".recipe")
  const name = data.forEach((d,index) => {
    (...)
    // !!! bind this to onModal
    recipecard.addEventListener("click",this.onModal.bind(this))
    (...)
}) }

因此,如果将“ this”绑定到onModal,则在click事件上调用的函数将使用您的类的上下文,因此它可以调用您的类的setState。

编辑

您也可以使用Nandu Kalidindi答案的第二部分。 箭头函数自动具有创建它们的位置的上下文,因此onLoad的上下文是类的上下文。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM