Я слышал, что передача стрелочной функции в качестве реквизита не идеальна, потому что она каждый раз создает новую функцию, что приведет к проблемам с производительностью. Однако я не совсем уверен, как полностью от них отойти, как видно на примере ниже:
class Home extends Component {
onCardPress = (message) =>{
alert(message)
}
render(){
return(
<View>
<Card
onCardPress = {this.onCardPress}
message = "Hello world!"
/>
</View>
)
}
}
class Card extends Component {
render(){
const { onCardPress , message } = this.props;
return(
<TouchableOpacity
activeOpacity = {0.8}
onPress = {()=>{onCardPress(message)}}
/>
)
}
}
Я пытался изменить onPress в Card на onPress = {onCardPress(message)}, но я знаю, что это не работает, потому что я вызываю функцию, а не передаю объект функции в onPress из TouchableOpacity. Каков «правильный» способ или наилучшая практика для удаления функции стрелки в TouchableOpacity, но при этом сохраняется возможность передачи параметра message из родительского компонента Home?





Если вы хотите избежать функции стрелки, вы должны использовать bind(). Стрелочные функции будут автоматически привязать "это".
class Home extends Component {
constructor(props) {
super(props);
this.onCardPress = this.onCardPress.bind(this);
}
onCardPress (message) {
alert(message)
}
render(){
return(
<View>
<Card
onCardPress = {this.onCardPress}
message = "Hello world!"
/>
</View>
)
}
}
class Card extends Component {
render(){
const { onCardPress , message } = this.props;
return(
<TouchableOpacity
activeOpacity = {0.8}
onPress = {onCardPress(message)}
/>
)
}
}
Вы можете сделать:
class Card extends Component {
pressHandler = () => this.props.onCardPress(this.props.message);
render() {
return (
<TouchableOpacity
activeOpacity = {0.8}
onPress = {this.pressHandler.bind(this)}
/>
);
} }
Небольшое преимущество заключается в том, что вы не создаете новую функцию каждый раз, когда запускается обработчик событий, однако в целом это довольно незначительно.
Насколько я понимаю, проблема заключается в вызове bind внутри render или возврате обработчика из еще одной лямбды, так как это будет каждый раз создавать новую функцию. Обычный способ обойти эту проблему — привязать функции обработчика в другом месте, например в конструкторе. В вашем случае это может выглядеть так:
constructor(props) {
....
this.onCardPress = this.onCardPress.bind(this);
}
...
<Card
onCardPress = {this.onCardPress}
message = "Hello world!"
/>
Учитывая альтернативный вариант, поскольку функция стрелки уже ответила в сообщении выше.
class Card extends Component {
onClick = () => {
const { onCardPress, message } = this.props;
onCardPress(message);
}
render(){
const { onCardPress , message } = this.props;
return(
<TouchableOpacity
activeOpacity = {0.8}
onPress = {this.onClick}
/>
)
}
}
Вам не нужно передавать свойство сообщения, потому что вы можете получить к нему доступ в любом месте компонента. Просто укажите функцию в свойстве onPress. И в этой функции просто получите доступ к свойству сообщения компонента.
class Home extends Component {
onCardPress = (message) => {
alert(message)
}
render() {
return (
<View>
<Card
onCardPress = {this.onCardPress}
message = "Hello world!"
/>
</View>
)
}
}
class Card extends Component {
onClick = () => {
const { message, onCardPress } = this.props;
onCardPress(message);
};
render() {
return (
<TouchableOpacity
activeOpacity = {0.8}
onPress = {this.onClick}
/>
)
}
}
Просто интересно, функционально это то же самое, что и версия функции стрелки, то есть производительность такая же? Или это позволяет избежать проблем с производительностью при использовании стрелочных функций?