Запустите приложение, если оно у вас не запущено (npm start
).
Как вы помните на прошлом скрине, у нас были предупреждения от . eslint - вспомогательный инструмент, который помогает поддерживать код в чистоте, на данный момент у нас следующие проблемы:
./src/App.js Line 50: Links must not point to "#". Use a more descriptive href or use a button instead jsx-a11y/href-no-hash Line 126: 'value' is assigned a value but never used no-unused-vars Line 140: 'agree' is assigned a value but never used no-unused-vars
Строка 50: у ссылки должен быть атрибут href не #, а что-то более вразумительное (замените на '#readmore').
Строка 126 - value - не используется, исправьте:
// было const { id, value } = e.currentTarget this.setState({ [id]: e.currentTarget.value }) // стало const { id, value } = e.currentTarget this.setState({ [id]: value })
Строка 140 - agree - не используется, исправьте:
// было const { name, text, bigText, agree } = this.state // стало const { name, text, bigText } = this.state
Поддерживайте свой код без предупреждений. Если вы не знаете о чем речь, например, сработало правило , не ленитесь. Изучайте документацию на
Наша задача - разбить огромный файл src/App.js
на компоненты.
Поддерживаются следующие импорты:
import A from 'A' // импорт по дефолту import { B } from 'B' // именованный импорт import * as C from 'C' // импорт "всего" в namespace C
С другой стороны поддерживаются следующие экспорты:
export default A // экспорт по дефолту export const B // именованный экспорт
Мы создадим несколько файлов, в каждом из которых будем пользоваться именованным экспортом. Затем в App импортируем.
Создайте директорию src/components
и в ней создайте файлы для каждого компонента, кроме <App />
.
Рассмотрим создание файла, на примере <Article />
:
src/components/Article.js
import React from 'react' // мы обязаны импортировать необходимые пакеты в каждом файле import PropTypes from 'prop-types' // у Article это react и prop-types // далее просто скопировано все что было, кроме последней строки class Article extends React.Component { state = { visible: false, } handleReadMoreClck = e => { e.preventDefault() this.setState({ visible: true }) } render() { const { author, text, bigText } = this.props.data const { visible } = this.state return ( <div className="article"> <p className="news__author">{author}:</p> <p className="news__text">{text}</p> {!visible && ( <a onClick={this.handleReadMoreClck} href="#readmore" className="news__readmore" > Подробнее </a> )} {visible && <p className="news__big-text">{bigText}</p>} </div> ) } } Article.propTypes = { data: PropTypes.shape({ id: PropTypes.number.isRequired, // добавили id, это число, обязательно author: PropTypes.string.isRequired, text: PropTypes.string.isRequired, bigText: PropTypes.string.isRequired, }), } export { Article } // именованный экспорт
Остальные файлы оформите аналогично.
Должна получиться следующая структура:
При этом, необходимо добавить import'ы в App.js и в News.js
src/App.js
import React from 'react' // импорт пакета prop-types удален, так как в этом файле prop-types не используется import { Add } from './components/Add' // ./ = текущая директория, import { News } from './components/News' // далее мы идем в директорию components и в нужный компонент import './App.css' const myNews = [ { id: 1, author: 'Саша Печкин', ...
src/components/News.js
import React from 'react' import PropTypes from 'prop-types' import { Article } from './Article' // идти в components не нужно, так как мы уже в этой директории class News extends React.Component { renderNews = () => { ...
Я думаю принцип понятен: в каждом файле мы импортируем то, что нам нужно относительно этого файла.
'../'
'../../'
'./'
'./components/Name'
'название библиотеки'
Наш App.js заметно похудел. Ориентироваться в коде стало удобнее.
myNews тоже можно выкинуть из этого файла.
src/data/newsData.json (экспорт json структуры по дефолту)
[ { "id": 1, "author": "Саша Печкин", "text": "В четверг, четвертого числа...", "bigText": "в четыре с четвертью часа четыре чёрненьких чумазеньких чертёнка чертили чёрными чернилами чертёж." }, { "id": 2, "author": "Просто Вася", "text": "Считаю, что $ должен стоить 35 рублей!", "bigText": "А евро 42!" }, { "id": 3, "author": "Max Frontend", "text": "Прошло 2 года с прошлых учебников, а $ так и не стоит 35", "bigText": "А евро опять выше 70." }, { "id": 4, "author": "Гость", "text": "Бесплатно. Без смс, про реакт, заходи - https: //maxpfrontend.ru", "bigText": "Еще есть группа VK, telegram и канал на youtube! Вся инфа на сайте, не реклама!" } ]
Итого: наш App.js нарядный:
src/App.js
import React from 'react' import { Add } from './components/Add' import { News } from './components/News' import newsData from './data/newsData' // импорт по дефолту import './App.css' class App extends React.Component { state = { news: newsData, } handleAddNews = data => { const nextNews = [data, ...this.state.news] this.setState({ news: nextNews }) } render() { return ( <React.Fragment> <Add onAddNews={this.handleAddNews} /> <h3>Новости</h3> <News data={this.state.news} /> </React.Fragment> ) } } export default App
Итого: мы не плохо прибрались, разобрались в импортах. Читать App.js стало удобнее, каждый компонент живет в отдельном файле.
Есть несколько подходов к организации файлов в больших проектах, мы лишь сделали первый шаг в этом направлении.
.