Порефакторим...
Last updated
Was this helpful?
Last updated
Was this helpful?
Was this helpful?
В течении всего учебника я учил вас думать о данных, а потом в CWP и gDSFR взял и сделал из образно stateless (хоть он и был через class - состояния у него не было) компонента - statefull. Это было сделано для удобства объяснений.
Смотрите, если мы откатим наш <News />
на два урока назад (когда компонент просто получал props), то мы сможем в <App />
использовать gDSFR и там "рубить спам". Таким образом, мы бы опять решили задачу без изменения stateless компонента.
Было: компонент <News />
умел отображать данные. Стало: компонент <News />
умеет отображать данные и помечать спам.
Задача: обрабатывать данные в <App />
, вернуть <News />
к прежнему "тупому" образу жизни.
Подсказка: вы запросто можете сделать все что нужно в <App />
, так как мы только что отработали этот прием.
Подсказка: в <App />
новости лежат в state, а не в props.
Напоминаю, как выглядел <News />
:
src/components/News.js
import React from 'react'
import PropTypes from 'prop-types'
import { Article } from './Article'
class News extends React.Component {
renderNews = ()
Полный код компонента <App />
src/App.js
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
Итого: