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

В течении всего учебника я учил вас думать о данных, а потом в 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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://max-frontend.gitbook.io/react-course-ru-v2/spam-filtr/porefaktorim.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
