> For the complete documentation index, see [llms.txt](https://max-frontend.gitbook.io/react-course-ru-v2/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://max-frontend.gitbook.io/react-course-ru-v2/spam-filtr/componentwillreceiveprops.md).

# componentWillReceiveProps

Давайте начнем со старого метода жизненного цикла ([componentWillReceiveProps](https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops)), который будет поддерживаться до React 17й версии. Нам нужно это знать, потому что много (очень много) кода уже написано и вам, наверняка, достанется такой проект.

*src/components/News.js*

```jsx
class News extends React.Component {
  componentWillReceiveProps(nextProps) {
    console.log({ nextProps })
    console.log({ oldProps: this.props })
  }
  ...
}

...

export { News }
```

![fresh news](/files/-LvLnWDIry00XAgyxHVe)

Давайте, мы отвлечемся на секунду и исправим старую ошибку - в компоненте `<Add />` у кнопки, сделайте текст "Добавить новость", вместо "Показать Alert".

Продолжим: CWRP в первом аргументе принимает "будущие props", значит мы можем по ним пробежаться, найти новость с "pubg" фрагментом, если она есть и пометить ее как "СПАМ".

Одно НО, так как мы хотим что-то изменять, значит у нас у компонента появляется состояние! **Обращаю внимание**: данная задача сейчас решается не оптимальным способом, мы просто учимся следующим моментам:

* как сделать state на основе props?
* как изменить состояние, на основе вновь пришедших props?

*src/components/News.js*

```jsx
...
class News extends React.Component {

  state = { // создали состояние
    filteredNews: this.props.data,
  }

  componentWillReceiveProps(nextProps) {
    console.log({ nextProps })
    console.log({ oldProps: this.props })
  }
  renderNews = () => {
    const { filteredNews } = this.state // используем состояние
    let newsTemplate = null

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

    return newsTemplate
  }
  render() {
    const { filteredNews } = this.state // аналогично, используем состояние

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

Изменений немного, просто внимательно пробегитесь по файлу - теперь данные берем из filteredNews, но при этом они нам изначально приходят в props (поэтому propTypes оставили без изменений).

Внутри *CWRP* можно безопасно использовать *setState*, так как это не приведет к дополнительной (лишней) перерисовке.

*src/components/News.js*

```jsx
componentWillReceiveProps(nextProps) {
  let nextFilteredNews = [...nextProps.data]

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

  this.setState({ filteredNews: nextFilteredNews })
}
```

В данном фрагменте ничего необычного, для тех кто в теме основ (я понимаю, что фраза "знать основы" набила оскомину, но их действительно нужно знать).

В `nextFilteredNews` склонировали весь массив новостей из "будущих" пропс, затем пробежались по нему, в if выяснили, есть ли pubg в введеном в bigText тексте, и если есть, заменили на "СПАМ".

Для тех, у кого есть пробелы:

* [toLowerCase](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) (MDN)
* [indexOf](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf) (MDN)

**Итого**:

* научились создавать *state* на основе *props*;
* научились обновлять *state* на основе новых *props* без лишней перерисовки;

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