我知道这种情况有很多答案,涉及使用绑定或箭头功能,但是我的情况有些不同。基本上,我想用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">×</span>
<ModalWindow datas= {data} index={this.state.setIndex} />
</div>
</div>
<div className ="recipe">
</div>
</div>
);
}
}
export default AddRecipe
答案 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的上下文即为类的上下文。