this.setState不是函数React

时间:2018-06-28 14:52:24

标签: javascript reactjs

我知道这种情况有很多答案,涉及使用绑定或箭头功能,但是我的情况有些不同。基本上,我想用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

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

OR

您甚至可以尝试使用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

答案 2 :(得分:0)

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

 componentDidMount() {
    this.onLoad()
 }

在构造函数中添加代码行

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

答案 3 :(得分:0)

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的上下文即为类的上下文。