Задать вопрос
@jondoeonoe

Возможно ли реализовать данную задачу «чище»?

Добрый день. Использую API Mastodon, для реализации клона твитера (в задаче именно это АПИ, а не твитера).
На текущий момент выполняю 3 раздела твитов: Tweets, Tweets with Replies, Media. Как в самом твитере -> https://twitter.com/swyx
Для этой реализации в документации АПИ есть нужный раздел, который позволяет получить все твиты пользователя:
https://github.com/tootsuite/documentation/blob/ma...

Сейчас у меня стоит задача сортировки твитов в нужные группы (из 3). То есть, в Медиа - все что с фото или ссылками, но в АПИ Мастодона нет такого квери парам. Only media подразумевает только картинки разумеется.

Tweets with Replies включает в себя твиты из группы Tweets + с ответами. Опять же, такого нет в АПИ.

Tweets включает в себя собственно обратное with Replies. Все кроме ответов.

На текущий момент, в компоненте Feeds, который отвечает за все 3 типа твитов, я делаю фетч по нужному урлу АПИ и достаю массив объектов твитов. Далее, я делаю проверки по нужным полям, то есть, если у твита не было репоста (reblog), то он будет выглядеть как твит нашего юзера, а если был, то мы используем данные пользователя, у которого сделали репост и тд.
in_reply_to_account_id - Твиты с ответом.
media_attachments - Изображения
includes(href) проверка, есть ли в тексте ссылка (значит в Медиа)

Я считаю, что код не очень мягко говоря, но как иначе я пока не знаю, в связи с тем, что апи не предоставляет нужного для меня. Вариант сменить АПИ невозможен. Я очень прошу помощи.

То есть примерно такое:

class Feeds extends Component {
  state = {
    error: false,
    feeds: []
  };

  componentDidMount() {
    this.getFeedInfo();
  }

  componentDidUpdate(prevProps) {
    if (prevProps.match.url !== this.props.match.url) {
      this.getFeedInfo();
    }
  }

  getFeedInfo = () => {
    fetch(
      `${api}/accounts/${this.props.match.url.slice(
        1
      )}/statuses?access_token=${token}`
    )
      .then(res => res.json())
      .then(
        feeds => {
          this.setState({
            feeds
          });
        },
        error => {
          this.setState({
            error
          });
        }
      );
  };

  render() {
    const { error, feeds } = this.state;
    if (error) {
      return <h3>Error: {error.message}. Can not load Feeds</h3>;
    }
    return (
      <React.Fragment>
        <Tabs />
        <Route
          exact
          path={`${this.props.match.url}`}
          render={() => (
            <TweetList>
              {feeds.map(feed => (
                <React.Fragment key={feed.id}>
                  {!feed.reblog ? (
                    !feed.in_reply_to_account_id && (
                      <Tweet
                        key={feed.id}
                        id={feed.id}
                        pinned={feed.pinned}
                        accountUrl={feed.account.id}
                        avatar={feed.account.avatar_static}
                        personNick={feed.account.username}
                        person={feed.account.display_name}
                        uri={feed.uri}
                        date={feed.created_at}
                        content={feed.content}
                        attachments={feed.media_attachments}
                        comments={feed.comments}
                        retweets={feed.reblogs_count}
                        likes={feed.favourites_count}
                        messages={feed.messages}
                        activeLike={feed.activeLike}
                      />
                    )
                  ) : (
                    <Tweet
                      reblog
                      key={feed.reblog.id}
                      id={feed.reblog.id}
                      accountUrl={feed.reblog.account.id}
                      userRetweet={feed.account.display_name}
                      pinned={feed.reblog.pinned}
                      avatar={feed.reblog.account.avatar_static}
                      personNick={feed.reblog.account.username}
                      person={feed.reblog.account.display_name}
                      uri={feed.reblog.uri}
                      date={feed.reblog.created_at}
                      content={feed.reblog.content}
                      attachments={feed.reblog.media_attachments}
                      comments={feed.reblog.comments}
                      retweets={feed.reblog.reblogs_count}
                      likes={feed.reblog.favourites_count}
                      messages={feed.reblog.messages}
                      activeLike={feed.reblog.activeLike}
                    />
                  )}
                </React.Fragment>
              ))}
            </TweetList>
          )}
        />
        <Route
          exact
          path={`${this.props.match.url}/with-replies`}
          render={() => (
            <TweetList>
              {feeds.map(feed => (
                <React.Fragment key={feed.id}>
                  {feed.reblog ? (
                    <Tweet
                      reblog
                      key={feed.reblog.id}
                      id={feed.reblog.id}
                      accountUrl={feed.reblog.account.id}
                      userRetweet={feed.account.display_name}
                      pinned={feed.reblog.pinned}
                      avatar={feed.reblog.account.avatar_static}
                      personNick={feed.reblog.account.username}
                      person={feed.reblog.account.display_name}
                      uri={feed.reblog.uri}
                      date={feed.reblog.created_at}
                      content={feed.reblog.content}
                      attachments={feed.reblog.media_attachments}
                      comments={feed.reblog.comments}
                      retweets={feed.reblog.reblogs_count}
                      likes={feed.reblog.favourites_count}
                      messages={feed.reblog.messages}
                      activeLike
                    />
                  ) : (
                    <Tweet
                      reply={feed.in_reply_to_account_id}
                      replyUser={feed.mentions}
                      accountUrl={feed.account.id}
                      key={feed.id}
                      id={feed.id}
                      pinned={feed.pinned}
                      avatar={feed.account.avatar_static}
                      personNick={feed.account.username}
                      person={feed.account.display_name}
                      uri={feed.uri}
                      date={feed.created_at}
                      content={feed.content}
                      attachments={feed.media_attachments}
                      comments={feed.comments}
                      retweets={feed.reblogs_count}
                      likes={feed.favourites_count}
                      messages={feed.messages}
                      activeLike={feed.activeLike}
                    />
                  )}
                </React.Fragment>
              ))}
            </TweetList>
          )}
        />
        <Route
          exact
          path={`${this.props.match.url}/media`}
          render={() => (
            <TweetList>
              {feeds.map(feed => (
                <React.Fragment key={feed.id}>
                  {(feed.media_attachments.length > 0 ||
                    feed.content.includes("href")) &&
                  !feed.in_reply_to_account_id &&
                  !feed.reblog ? (
                    <Tweet
                      key={feed.id}
                      id={feed.id}
                      accountUrl={feed.account.id}
                      pinned={feed.pinned}
                      avatar={feed.account.avatar_static}
                      personNick={feed.account.username}
                      person={feed.account.display_name}
                      uri={feed.uri}
                      date={feed.created_at}
                      content={feed.content}
                      attachments={feed.media_attachments}
                      comments={feed.comments}
                      retweets={feed.reblogs_count}
                      likes={feed.favourites_count}
                      messages={feed.messages}
                      activeLike={feed.activeLike}
                    />
                  ) : null}
                </React.Fragment>
              ))}
            </TweetList>
          )}
        />
      </React.Fragment>
    );
  }
}
  • Вопрос задан
  • 220 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
Код особо не разбирал. Скажу лишь, что вам компонент лучше разбить на несколько:
render () {
  const { match: { url } } = this.props;
  return (
    <Switch>
      <Route exact path={url} content={Tweets} />
      <Route exact path={url + '/with-replies'} content={WithReplies} />
      <Route exact path={url + '/media'} content={Media} />
    </Switch>
  )
}


Вместо:
render() {
  return someCondition ? (
      <Component
        prop1={a.prop1}
        prop2={a.prop2}
        prop3={a.prop3}
        prop4={a.prop4}
        prop5={a.prop5}
      />
    ) : (
      <Component
        prop1={b.prop1}
        prop2={b.prop2}
        prop3={b.prop3}
        prop4={b.prop4}
        prop5={b.prop5}
      />
    );
}

Лучше:
render() {
  const c = someCondition ? a : b;

  return (
    <Component
      prop1={c.prop1}
      prop2={c.prop2}
      prop3={c.prop3}
      prop4={c.prop4}
      prop5={c.prop5}
    />
  );
}


Всместо :
render() {
  return (
    <Wrapper>
      {condition1 &&
         condition2 &&
         condition3 &&
         condition4 && (
           <Component />
       )}
    </Wrapper>
  )
}


Лучше:
render() {
  const shouldShowComponent = condition1 && condition2 && condition3 && condition4; 

  return (
    <Wrapper>
      {shouldShowComponent && <Component />}
    </Wrapper>
  );
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы