LINUX.ORG.RU

Кошерно ли использование замыканий при передаче колбеков в React-компонент?

 , ,


0

1

У меня есть компонент, который выводит «комментарий». Выглядит он вот так:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

import styles from './Comment.css';

import CommentInput from '../CommentInput/CommentInput';

class Comment extends Component {
  render() {
    const profileLink = `https://instagram.com/${this.props.name}`;
    return (
      <div className={styles.Comment}>
        <a href={profileLink} target="_blank">
          { this.props.avatar 
            ? <img className={styles.Avatar} src={this.props.avatar} />
            : <i className={`far fa-user ${styles.AvatarTemplate}`}></i> 
          }
        </a>
        <div className={styles.Data}>
          <div className={styles.Text}>
            <a className={styles.ProfileLink} href={profileLink} target="_blank">{this.props.name}</a>
            <span className={styles.CommentText}>{this.props.text}</span>
          </div>
          <div className={styles.BottomLine}>
            <div className={styles.Date}>
              {this.props.date}
            </div>
            <button className={styles.Button} onClick={() => this.props.callbackDeleteClick()}>Удалить комментарий</button>
            <button className={styles.Button} onClick={() => this.props.callbackAnswerClick()}>Ответить</button>
          </div>
          { this.props.showInput && 
            <div className={styles.CommentInputWraper}>
              <CommentInput 
                withoutBackgorund={true} 
                callbackChange={this.props.callbackCommentEdit} 
                callbackSend={this.props.callbackCommentSend}
                text={this.props.answerText} 
              />
            </div> 
          }
        </div>
      </div>
    );
  }
}

Comment.propTypes = {
  ...
};

export default Comment;

Но суть не в нем, а в том, как я им пользуюсь:

  createComments(posts, selectedDialogId, selectedCommentId, answers, answerCallback, deleteCallback, answerEditCallback, answerSendCallback) {
    const selectedPost = posts.find(post => post.id === selectedDialogId);
    const comments = selectedPost ? selectedPost.newComments : [];
    return comments.map((comment, index) => {
      return <Comment 
        key={index}
        name={comment.name}
        text={comment.text}
        date={comment.date}
        avatar={comment.avatar}
        deleted={comment.deleted || false}
        showInput={comment.id === selectedCommentId}
        answerText={answers[comment.id] || ''}
        callbackAnswerClick={() => answerCallback(comment.id)}
        callbackDeleteClick={() => deleteCallback(selectedPost.id, comment.id)}
        callbackCommentEdit={(text) => answerEditCallback(comment.id, text)}
        callbackCommentSend={() => answerSendCallback(selectedPost.id, comment.id, answers[comment.id] || '')}
      />;
    });
  }
Обратите внимания на колбеки - я передаю часть данных в них с помощью замыканий, типа тех же comment.id.

Мне такой подход нравится тем, что компонент Comment не хранит данные, которые, по сути, ему для работы не нужны (типа того же comment.id).

Не нравится из за того, что, логика, по сути, полностью определяется в родительском компоненте, где используется Comment. Хотя лол, я так сформулировал, что мне это уже не кажется недостатком.

В общем, что скажете?

П.С. По какой-то причине, сломались переносы в коде. Кастаните плиз кого либо, кто причастен к работе разукрашки кода.

Deleted

Не называется ли это умным словом «подъём состояния»?

den73 ★★★★★ ()

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

sholom ()

типичный реакт код :-)

да, так можно делать и зачастую нужно, но если будешь много таких лямбд плодить на каждый рендер, то gc тебе спасибо не скажет

anonymous ()
Ответ на: комментарий от anonymous

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

Посмотри на GC

max_lapshin ★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.