渲染列表后,我从第三方API获得了食谱列表。当我按下“收藏夹”按钮时,我想将特定的添加到收藏夹列表中。但是,每当我尝试呈现配方列表时,我都会收到错误消息“ TypeError:无法读取未定义的属性'addtoFavorites'”
任何帮助将不胜感激。
当我删除“ onClick = {this.addtoFavorites.bind(this)}”时,组件将按预期方式呈现。我不知道为什么addtoFavorites未定义
class RecipeList extends Component {
addtoFavorites = (ev) => {
const val = ev.target.dataset.value;
this.props.recipeToFavorite(val);
console.log(val)
renderRecipe(recipeData) {
let recipeName = recipeData.recipeName;
let recipeId = recipeData.id;
let recipeIngredients = recipeData.ingredients.join(", ");
let recipeURL = "https://www.yummly.com/recipe/" + recipeData.id;
let recipeImage = recipeData.smallImageUrls;
var recipeDataObj = { name:recipeName, recipeID:recipeId, recipeImage:recipeImage, recipeURL: recipeURL }
}
return (
<div>
<div key={recipeData.id}>
<div>
<img
src= {recipeImage}
alt="FoodPic"
/>
<h4> {recipeName} </h4>
<div>
<h3>Ingredients</h3>
</div>
<ul>
{recipeIngredients}
</ul>
<h6>
<a href={recipeURL}>
Recipe
</a>
</h6>
</div>
</div>
<button
onClick={this.addtoFavorites.bind(this)}
data-value={recipeDataObj}
>
Fav
</button>
</div>
);
}
render() {
return (
<div>
<h2 className="">Recipes</h2>
<div className="">{this.props.recipes.map(this.renderRecipe)}</div>
</div>
);
}
}
function mapStateToProps({ recipes }) {
//console.log("List Recipes", recipes)
return {
recipes
};
}
export default connect(mapStateToProps)(RecipeList);
import _ from "lodash";
import React, { Component } from "react";
import { compose } from "redux";
import { connect } from "react-redux";
import * as actions from "../Actions";
class FoodList extends Component {
componentDidMount() {
this.props.fetchFoodList();
}
addIngredientToPot = ev => {
const val = ev.target.dataset.value;
this.props.addToPot(val);
};
onDeleteClick = ev => {
const val = ev.target.dataset.value;
this.props.deleteFood(val);
this.props.fetchFoodList();
};
displayFoodList() {
return _.map(this.props.foods, food => {
return (
<tr key={food._id}>
<td
onClick={this.addIngredientToPot.bind(this)}
data-value={food.name}
>
{food.name}
</td>
<td>{food.type}</td>
<td>{food.count}</td>
<td>{food.created_at}</td>
<td>
<button
data-value={food._id}
onClick={this.onDeleteClick.bind(this)}
>
Throw Out
</button>
</td>
</tr>
);
});
}
render() {
return (
<div>
<div>
<div>
<div />
</div>
<div>
<div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Count</th>
<th>Date Added</th>
<th>Throw Out</th>
</tr>
</thead>
<tbody>{this.displayFoodList()}</tbody>
</table>
</div>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
foods: state.foods,
pot: state.pot
};
}
export default compose(
connect(
mapStateToProps,
actions
)
)(FoodList);
答案 0 :(得分:0)
尝试将 addtoFavorites 方法更改为常规函数,而不是像这样的箭头函数。
class RecipeList extends Component {
constructor() {
this.addtoFavorites = this.addtoFavorites.bind(this);
}
addtoFavorites (ev){
const val = ev.target.dataset.value;
this.props.recipeToFavorite(val);
console.log(val)
}
renderRecipe(recipeData) {
let recipeName = recipeData.recipeName;
let recipeId = recipeData.id;
let recipeIngredients = recipeData.ingredients.join(", ");
let recipeURL = "https://www.yummly.com/recipe/" + recipeData.id;
let recipeImage = recipeData.smallImageUrls;
var recipeDataObj = { name:recipeName, recipeID:recipeId, recipeImage:recipeImage, recipeURL: recipeURL }
}
return (
<div>
<div key={recipeData.id}>
<div>
<img
src= {recipeImage}
alt="FoodPic"
/>
<h4> {recipeName} </h4>
<div>
<h3>Ingredients</h3>
</div>
<ul>
{recipeIngredients}
</ul>
<h6>
<a href={recipeURL}>
Recipe
</a>
</h6>
</div>
</div>
<button
onClick={this.addtoFavorites}
data-value={recipeDataObj}
>
Fav
</button>
</div>
);
}
render() {
return (
<div>
<h2 className="">Recipes</h2>
<div className="">{this.props.recipes.map(this.renderRecipe)}</div>
</div>
);
}
}
function mapStateToProps({ recipes }) {
//console.log("List Recipes", recipes)
return {
recipes
};
}
export default connect(mapStateToProps)(RecipeList);
答案 1 :(得分:0)
如果您从文档中阅读了主要概念,则在handling events下对此进行了说明。
You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default
。了解有关在MDN上自动装箱的更多信息
arrow functions
也没有自己 this
。 (MDN)因此,当您执行this.addtoFavorites.bind(this)
时,没有this
要绑定。
所以处理事件的可能方法(根据文档):
将处理程序定义为常规javascript函数并绑定到构造函数中,因此在您情况下
constructor(props) {
// This binding is necessary to make `this` work in the callback
this.addtoFavorites = this.addtoFavorites.bind(this);
}
function addtoFavorites (ev) {
使用实验性的公共类字段语法,您可以使用类字段正确地绑定回调(不确定这是否仍处于实验性):
// This syntax ensures `this` is bound within handleClick.
// Warning: this is *experimental* syntax.
addtoFavorites = (ev) => {
...
在回调中使用箭头功能
addtoFavorites = (ev) => {
onClick={(e) => this.addtoFavorites(e)}
但是请注意,如果您使用此解决方案(来自docs):此语法的问题是,每次LoggingButton呈现时都会创建一个不同的回调。在大多数情况下,这很好。但是,如果将此回调作为对较低组件的支持传递,则这些组件可能会进行额外的重新渲染。
React的建议是使用binding
解决方案。
我们通常建议在构造函数中进行绑定或使用类字段语法进行绑定,以避免此类性能问题。