Попробуйте заменить метод addtoFoving на обычную функцию вместо функции стрелки, как эта
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);
Если вы прочитали Основные понятия из документов, это объясняется в Обработка событий .
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) {
[1121 ] используя экспериментальный синтаксис открытых полей классов , вы можете использовать поля классов для правильной привязки обратных вызовов (не уверен, если это все еще экспериментально):
// This syntax ensures `this` is bound within handleClick.
// Warning: this is *experimental* syntax.
addtoFavorites = (ev) => {
...
с использованием функции стрелки в callback
addtoFavorites = (ev) => {
onClick={(e) => this.addtoFavorites(e)}
Обратите внимание, однако, если вы используете это решение (из документов): Проблема с этим синтаксисом заключается в том, что каждый раз при рендеринге LoggingButton создается другой обратный вызов. В большинстве случаев это нормально. Однако, если этот обратный вызов передается в качестве поддержки более низким компонентам, эти компоненты могут выполнить дополнительный повторный рендеринг.
React рекомендует использовать решение binding
.
Мы обычно рекомендуем связывание в конструкторе или использование синтаксиса полей классов, чтобы избежать такого рода проблем с производительностью.