Порефакторим...

Для начала, удалите вовсе компонент <Comments />const Comments... соответственно).

Далее, давайте представим: у наших новостей появляются какие-то дополнительные поля, пользователь начинает взаимодействовать с ними, например "пометить как прочитанное" и так далее. Нам было бы удобно, чтобы каждая новость была представлена отдельным компонентом.

Задача: <News /> должен рендерить список компонентов <Article />. Каждый компонент <Article /> должен получать соответствующие данные, например: первый экземпляр получит первый элемент массива, второй - второй и так далее.

То есть, раньше в map мы возвращали JSX-разметку. Но мы так же можем возвращать и компонент.

Попробуйте сами, а потом смотрите решение ниже.

Подсказка #1: if-else нашего компонента <News />

if (data.length) {
  newsTemplate = data.map(function(item) {
    return <Article key={item.id} data={item}/>
  })
} else {
  newsTemplate = <p>К сожалению новостей нет</p>
}

Подсказка #2 (по сути решение задачи): компонент <Article />

class Article extends React.Component {
  render() {
    const { author, text } = this.props.data
    return (
      <div className="article">
        <p className="news__author">{author}:</p>
        <p className="news__text">{text}</p>
      </div>
    )
  }
}

Что любопытно, больше не изменилось ни-че-го.

Добавьте заголовок "Новости" в <App /> перед компонентом <News />

Добавьте красоты (CSS) по вкусу, либо возьмите мой вариант:

С новыми стилями, код сценария выглядит так:

index.html

В целом меня устраивает почти все. Осталось немного отполировать метод render компонента <News />. Правило следующее: стараемся в render держать как можно меньше кода, чтобы его было легко читать вашим коллегам. Для этого, мы newsTemplate будем заполнять внутри нового метода, который будем вызывать в render.

Что примечательного в этом коде?

Мы создали метод renderNews (внутри class) с помощью так называемой "жирной стрелочной функции" (запись вида methodName = () => ...). При такой записи, внутри функции мы не теряем контекст this. То есть, можем обращаться к this.props, например.

Почему мы метод render не описываем через жирную стрелочную функцию? Потому что, это метод жизненного цикла react-компонента, и туда this "прокидывает" уже сам react.

Далее, так как мы renderNews создали в качестве метода, значит внутри компонента, мы должны обращаться к нему как this.XXX (где XXX - название метода, в нашем случае renderNews).

Что же изменилось, спросите вы? Было много кода в render, стало чуть выше. Дело в том, что когда ваши компоненты разрастутся, очень удобно иметь "рендер" хорошо читаемым, то есть таким, в котором все лишнее спрятано.

Посмотрим, что вышло в итоге:

Исходный код на данный момент.

Last updated

Was this helpful?