У меня есть некоторые сомнения, пытаясь понять, как реакция работает с функциями в качестве реквизита, передавая их дочерним компонентам. Я уже видел несколько руководств, но на данный момент не понял свою проблему.
По сути, у меня есть простой компонент, который передает список вниз, и другой компонент, который обрабатывает список с помощью Array.map для отображения другого компонента.
В основном у меня есть следующее:
App.js -> Цитаты -> Цитата.
И я хочу обработать щелчок по компоненту Quote. Поэтому каждый раз, когда пользователь нажимает Quote, я хочу обрабатывать его в APP.js.
Я уже пытался передать ссылку в качестве опоры и в компоненте кавычек app.js для вызова функции, но это не сработало.
Это то, что я пробовал до сих пор:
App.js
import React, { Component } from 'react';
import classes from './App.module.css';
import Quotes from '../components/quotes/quotes'
class App extends Component {
state = {
quotes: [
{ id: 1, text: "Hello There 1" },
{ id: 2, text: "Hello There 2" },
{ id: 3, text: "Hello There 3" },
{ id: 4, text: "Hello There 4" }
],
clickedQuote: "none"
}
handleClickedQuote (id) {
console.info(id)
const quoteIndex = this.state.quotes.findIndex(q => q.id === id)
this.setState({
clickedQuote: this.state.quotes[quoteIndex].text
})
}
render() {
return (
<div className = "App">
<div className = {classes['quotes-wrapper']}>
<Quotes clicked = {this.handleClickedQuote} quotes = {this.state.quotes}/>
<p>clicked quote {this.state.clickedQuote}</p>
</div>
</div>
);
}
}
export default App;
Цитаты.js
import React from 'react';
import Quote from './quote/quote'
const quotes = (props) => props.quotes.map((quote) => {
return (
<Quote clicked = {props.clicked} text = {quote.text}/>
)
})
export default quotes
Цитата.js
import React from 'react';
import classes from './quote.module.css'
const quote = (props) => {
return (
<div onClick = {() => props.clicked(props.id)} className = {classes.quote}>
<p className = {classes['quote-text']}>{props.text}</p>
</div>
)
}
export default quote
Мне нужно получить идентификатор hanleClickedQuote в функции App.js. Что я делаю неправильно?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вам нужно явно передать идентификатор в качестве реквизита. Итак, в Quotes.js в вашем map(),
что-то типа:
<Quote id = {quote.id} clicked = {props.clicked} text = {quote.text}/>
Обновление: как сказал @Ashkan в своем ответе, вам также необходимо правильно связать свой обработчик.
не думаю, что это главная проблема
Я думаю, что это основная/самая очевидная проблема. Если они правильно свяжут свою функцию, как вы предложили, код все равно не будет делать то, что они хотят.
То же самое касается другой проблемы. Даже если вы передадите реквизит, код выдаст исключение, поскольку this.state не определено. Просто пытаюсь направить его по правильному пути, поскольку, исходя из опыта, многие люди сталкиваются с этой проблемой, когда начинают использовать React. Как вы сказали, эта ошибка немного более очевидна и ее легче отладить, чем проблему, которая требует, чтобы вы знали, почему «это» получает неправильное значение.
Конечно, и то, и другое вместе полезнее.
Ну, в вашем коде есть две вещи, которые идут очень неправильно. Первая — распространенная проблема в сообществе JS. Я предлагаю вам подробнее изучить использование ключевого слова this. в App.js вы определяете свой метод как объявление функции.
handleClickedQuote(id) {
console.info(id)
const quoteIndex = this.state.quotes.findIndex(q => q.id === id)
this.setState({
clickedQuote: this.state.quotes[quoteIndex].text
})
}
Теперь ключевое слово «this» в объявлениях функций устанавливается динамически, что означает, что здесь «this» фактически устанавливается при вызове функции, и, поскольку это обработчик событий, значение «this» на самом деле будет вашим событием! Вы можете проверить это. Но мы хотим, чтобы «это» относилось к нашему классу, чтобы мы могли получить доступ к состоянию.
Есть два способа исправить это, первый:
Вы можете привязать правильное значение для this в конструкторе вашего класса App.js следующим образом (по-старому):
constructor(props) {
super(props);
this.handleClickedQuote = this.handleClickedQuote.bind(this);
}
Это заменяет метод в вашем классе версией, которая использует правильное значение this на этапе построения вашего объекта.
Или, что еще проще, вы можете использовать стрелочную функцию, так как ключевое слово this в стрелочной функции задается лексически:
handleClickedQuote = id => {
console.info(id);
const quoteIndex = this.state.quotes.findIndex(q => q.id === id);
this.setState({
clickedQuote: this.state.quotes[quoteIndex].text
});
}
ПРИМЕЧАНИЕ. В стрелочной функции значение this в основном относится ко всему, что находится за пределами этого блока кода, который в данном случае является всем вашим объектом.
Также у вас есть небольшая ошибка в вашем коде, о которой кто-то упомянул. На самом деле вы забыли передать идентификатор цитаты в качестве реквизита компоненту Quote. Но это всего лишь небольшая оплошность. Важно знать, что эта проблема связана не столько с React, сколько с самим JS. Мой совет — немного углубиться в JS и изучить все тонкости и технические особенности языка. Это избавит вас от многих хлопот в будущем. Также поработайте над своими навыками отладки, чтобы такие ошибки, как отсутствующая опора, не пропадали так легко.
Удачи
Я как бы знал о первом ответе, который вы мне дали, просто забыл об этом и подумал, что проблема не в этом. Просто быстрый вопрос, когда я передаю функцию, которая обрабатывается в компоненте с отслеживанием состояния, как указано выше, в дочерний компонент. Я должен использовать что-то вроде () => function(), когда я запускаю функцию, как в цитате, верно?
@FilipeCosta Я не думаю, что в этом есть какие-то недостатки. Альтернативой может быть повторное использование привязки, только на этот раз вы привязываете параметры вместо переменной this. Лично я предпочитаю функцию стрелки, как и вы, если только вы не используете ES6 и не поддерживаете ее.
console.info(id)работает?\