Как передать разные обработчики событий для одного и того же события? - PullRequest
0 голосов
/ 07 января 2020

У меня есть компонент-реагирующий, который отображает 2 иконки для , отмечающих избранные и при написании комментария , как показано ниже:

function RenderDish(props) {
const dish = props.dish;

if (dish != null) {
    return (
        <Card featuredTitle={dish.name} image={{ uri: baseUrl + dish.image }}>
            <Text style={{ margin: 10 }}>
                {dish.description}
            </Text>
            <View style={{ display: "flex", flexDirection: "row", alignItems: "center", justifyContent: "center" }}>
                <Icon raised reverse name={props.favorite ? 'heart' : 'heart-o'} type='font-awesome' color='#f50'
                    onPress={() => props.favorite ? console.log('Aleady Favorite') : props.onFavorite()} />
                <Icon raised reverse name='pencil' type='font-awesome' color='#3b5998'
                    onPress={() => props.onComment()} />
            </View>
        </Card>
    );
}
else {
    return (<View></View>);
}} 

Я вызов этого функционального компонента из внешнего компонента, как показано ниже:

<RenderDish dish={this.props.dishes.dishes[+dishId]}
                favorite={this.props.favorites.some(el => el === dishId)}
                onFavorite={() => this.markFavorite(dishId)}
                onComment={() => this.toggleModal()} />  

Я уже реализовал методы toggleModal() и markFavorite(), и все работает, как ожидалось , но мой вопрос является: Есть ли другой способ передать 2 или более различных обработчиков событий через один реквизит? Например, Есть ли способ сказать что-то вроде: <RenderDish dish={xyz} onPress={()=> handler1 AND handler2}. Или есть какая-нибудь изящная альтернатива тому, что я сделал (если бы у меня было 5 кнопок, мне понадобилось бы 5 реквизитов :()?

Ответы [ 3 ]

0 голосов
/ 07 января 2020

Попробуйте что-то вроде ниже. Передайте методы обработчика как объект в подпорке.



function Button(props) {
  return (
    <div>
      <button type="button" onClick={props.onPress.handler1} >Handler1</button>
      <button type="button" onClick={props.onPress.handler2} >Handler2</button>
    </div>

  );
}


class Home extends Component {


  handler1() {
    console.log('handler 1');
  }

  handler2() {
    console.log('handler 2');
  }


  render() {
    return (
      <div>
        <Button onPress={{ handler1: this.handler1, handler2: this.handler2 }} />
      </div>
    )
  }
}
0 голосов
/ 07 января 2020

То, как вы это сделали, возможно, самый распространенный и вполне приемлемый.

Обычно это не проблема, если есть только несколько обработчиков (и они не передаются глубоко).

Вы могли бы объединить их в объект и единую опору, но я обычно не вижу, как это делается таким образом, и я не думаю, что есть сильная выгода.

Вы также можете передать несколько реквизитов в качестве одного спреда без необходимости связывать их в один реквизит.

Если вы начнете получать больше обработчиков, чем вам удобно, то, вероятно, самое время посмотреть, как вы справляетесь с управлением состоянием. Вам может быть лучше с редуктором и диспетчерскими действиями в этой точке.


Обновление

Несколько других замечаний о вашем коде:

  1. Вы можете деструктурировать реквизиты для более удобного использования.
  2. Вы не можете нужен отдельный закрывающий тег для View, если нет содержимого.
  3. Вам не нужно создавать новые функции стрелок для обработчиков событий, если все, что вы делаете, это вызывает другую функцию стрелки. Вы можете просто установить для нее функцию первой стрелки.
  4. Рассмотрим троицу, чтобы разрешить неявный возврат.
function RenderDish({dish, favorite, onFavorite, onComment}) =>
    dish
    ?   <Card featuredTitle={dish.name} image={{ uri: baseUrl + dish.image }}>
            <Text style={{ margin: 10 }}>
                {dish.description}
            </Text>
            <View style={{ display: "flex", flexDirection: "row", alignItems: "center", justifyContent: "center" }}>
                <Icon raised reverse name={favorite ? 'heart' : 'heart-o'} type='font-awesome' color='#f50'
                    onPress={() => favorite ? console.log('Aleady Favorite') : onFavorite()} />
                <Icon raised reverse name='pencil' type='font-awesome' color='#3b5998'
                    onPress={onComment} />
            </View>
        </Card>
    :   <View/>

Я бы больше сосредоточился на этих элементах, чем на связывании этих элементов. две функции.

0 голосов
/ 07 января 2020

Вы можете иметь свои обработчики в одной функции и вызывать функцию в onPress. или просто

onPress={()=> {handler1, handler2}}
...