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

В течении всего учебника я учил вас думать о данных, а потом в CWP и gDSFR взял и сделал из образно *stateless* (хоть он и был через *class* - состояния у него не было) компонента - *statefull*. Это было сделано для удобства объяснений.

Смотрите, если мы откатим наш `<News />` на два урока назад (когда компонент просто получал props), то мы сможем в `<App />` использовать gDSFR и там "рубить спам". Таким образом, мы бы опять решили задачу без изменения stateless компонента.

Было: компонент `<News />` умел отображать данные. Стало: компонент `<News />` умеет отображать данные и помечать спам.

**Задача**: обрабатывать данные в `<App />`, вернуть `<News />` к прежнему "тупому" образу жизни.

**Подсказка**: вы запросто можете сделать все что нужно в `<App />`, так как мы только что отработали этот прием.

**Подсказка**: в `<App />` новости лежат в *state*, а не в *props*.

Напоминаю, как выглядел `<News />`:

*src/components/News.js*

```jsx
import React from 'react'
import PropTypes from 'prop-types'
import { Article } from './Article'

class News extends React.Component {
  renderNews = () => {
    const { data } = this.props
    let newsTemplate = null

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

    return newsTemplate
  }
  render() {
    const { data } = this.props

    return (
      <div className="news">
        {this.renderNews()}
        {data.length ? (
          <strong className={'news__count'}>
            Всего новостей: {data.length}
          </strong>
        ) : null}
      </div>
    )
  }
}

News.propTypes = {
  data: PropTypes.array.isRequired,
}

export { News }
```

## Решение

Полный код компонента `<App />`

*src/App.js*

```jsx
import React from 'react'
import { Add } from './components/Add'
import { News } from './components/News'
import './App.css'

class App extends React.Component {
  state = {
    news: null,
    isLoading: false,
  }
  static getDerivedStateFromProps(props, state) {
    let nextFilteredNews

    // смотрим в state.news (ранее смотрели в props)
    // и проверяем, чтобы не клоинировать null
    // например, в момент первой отрисовки
    if (Array.isArray(state.news)) {
      nextFilteredNews = [...state.news]

      nextFilteredNews.forEach((item, index) => {
        if (item.bigText.toLowerCase().indexOf('pubg') !== -1) {
          item.bigText = 'СПАМ'
        }
      })

      return {
        filteredNews: nextFilteredNews,
      }
    }

    return null
  }
  componentDidMount() {
    this.setState({ isLoading: true })
    fetch('http://localhost:3000/data/newsData.json')
      .then(response => {
        return response.json()
      })
      .then(data => {
        setTimeout(() => {
          this.setState({ isLoading: false, news: data })
        }, 1000) // изменил таймер на 1000, чтобы не ждать долго
      })
  }
  handleAddNews = data => {
    const nextNews = [data, ...this.state.news]
    this.setState({ news: nextNews })
  }
  render() {
    const { news, isLoading } = this.state

    return (
      <React.Fragment>
        <Add onAddNews={this.handleAddNews} />
        <h3>Новости</h3>
        {isLoading && <p>Загружаю...</p>}
        {Array.isArray(news) && <News data={news} />}
      </React.Fragment>
    )
  }
}

export default App
```

**Итого**:

[Исходный код](https://github.com/maxfarseer/react-course-ru-v2/tree/chp18-reafactor-part-2)
