javascript - 如何让 React 中的 onClick 处理具有多个兄弟姐妹的单个元素?
问题描述
我是 React 新手,在尝试触发 onClick 事件时遇到问题。我有事件工作,当它被点击时,div 出现并重新出现。问题是,如果我按下特定项目的按钮,则会出现所有 div,而不是我刚刚单击按钮的 div。如何使我单击的按钮仅在该特定元素上触发。
这是我的代码:
类 App 扩展 React.Component {
constructor(props) {
super(props)
this.state = {
userInput: '',
getRecipe: [],
ingredients: "none"
}
}
handleChange = (e) => {
this.setState({
userInput: e.target.value
})
}
handleSubmit = (e) => {
e.preventDefault()
const getData = () => {
fetch(`https://api.edamam.com/search?q=${this.state.userInput}&app_id=${APP_ID}&app_key=${APP_KEY}&from=0&to=18`)
.then(res => {
return res.json()
}).then(data => {
this.setState({
getRecipe: data.hits
})
})
}
getData()
}
// this is where the button logic comes in
getIngredients = (e) => {
e.preventDefault()
if (this.state.ingredients === 'none') {
this.setState({
ingredients: "block"
})
} else {
this.setState({
ingredients: "none"
})
}
}
render() {
return (
<div className="recipes">
<Nav changed={this.handleChange} submit={this.handleSubmit} />
<Content
userInput={this.state.userInput}
recipe={this.state.getRecipe}
getIngredients={this.getIngredients}
ingredients={this.state.ingredients} />
</div>
)
}
}
const Content = ({ userInput, recipe, getIngredients, ingredients }) => {
return (
<div>
<h2 className="userinputtitle"> {userInput} </h2>
<div className="containrecipes">
{recipe.map(rec => {
return (
<div key={rec.recipe.label} className="getrecipes">
<h1 className="recipetitle" key={rec.recipe.label}>{rec.recipe.label.toUpperCase()}</h1>
<img src={rec.recipe.image}></img>
<h4 className="health"> Health Labels: {rec.recipe.healthLabels.join(', ')}</h4>
<h4 > Diet Label: {rec.recipe.dietLabels}</h4>
<h4 > Calories: {Math.floor(rec.recipe.calories)}</h4>
<h4 className="cautions"> Cautions: {rec.recipe.cautions}</h4>
<div>
<h4>{rec.recipe.digest[0].label + ":" + " " + Math.floor(rec.recipe.digest[0].total) + "g"}</h4>
<h4>{rec.recipe.digest[1].label + ":" + " " + Math.floor(rec.recipe.digest[1].total) + "g"}</h4>
<h4>{rec.recipe.digest[2].label + ":" + " " + Math.floor(rec.recipe.digest[2].total) + "g"}</h4>
</div>
// the button is clicked here, yet all div fire at the same time
<button onClick={getIngredients} className="getingredients">Ingredients</button>
{rec.recipe.ingredients.map(i => {
return (
<div style={{ display: ingredients }} className="containingredients">
< ul className="ingredients">
<li className="ingredient">{i.text}</li>
</ul>
</div>
)
})}
</div>
)
})}
</div>
</div>
)
}
解决方案
更新getIngredients
以使用配方 ID 并将其保存在状态中。
切换单一配方成分
this.state = {
userInput: '',
getRecipe: [],
ingredientsId: null
}
...
getIngredients = recipeId => e => {
e.preventDefault();
this.setState(prevState => ({
ingredientsId: prevState.ingredientsId ? null : recipeId,
}));
}
...
<Content
userInput={this.state.userInput}
recipe={this.state.getRecipe}
getIngredients={this.getIngredients}
ingredientsId={this.state.ingredientsId} // <-- pass id
/>
有条件地设置显示样式在Content
.
const Content = ({ userInput, recipe, getIngredients, ingredientsId }) => {
...
<button
onClick={getIngredients(recipe.id)} // <-- pass id
className="getingredients"
>
Ingredients
</button>
<div
style={{
// set display style
display: ingredientsId === recipe.id ? "block" : "none"
}}
className="containingredients"
>
<ul className="ingredients">
<li className="ingredient">{i.text}</li>
</ul>
</div>
...
切换多个配方成分
与上述相同,略有改动
状态是地图
this.state = {
userInput: '',
getRecipe: [],
ingredientsId: {},
}
在处理程序中切换 id
getIngredients = recipeId => e => {
e.preventDefault();
this.setState(prevState => ({
ingredientsId: {
...prevState.ingredientsId,
[recipeId]: !prevState.ingredientsId[recipeId]
},
}));
}
在传递的地图中查找 recipeId
style={{
// set display style
display: ingredientsId[recipe.id] ? "block" : "none"
}}
推荐阅读
- javascript - 如何通过 Google API 将我的特殊日期转换为时区
- jquery - 如何编写jquery输入自动完成
- node.js - 如何将从 router.get 中的 request.get 收到的错误解释为 express.js 中的错误?
- c++ - RTSP 流媒体服务器 C++
- django-rest-framework - “日期格式错误”Angular 10 Rest Django
- javascript - js拖拽img与删除当前目标图片
- java - 即使在点击 return 语句后循环继续
- python - discord bot在python中向用户添加角色
- jupyter-notebook - 使用 sympy 在 Jupyter notebook 中显示方程
- scala - 如何保存响应主体并在整个 Gatling 执行过程中使用它