Сообщения

Сообщения за июль, 2019

setState() - удаление элемента

Изображение
В предыдущей части мы сумели передать событие клика с кнопки элемента TodoListItem в компонент App. В  App находится массив todoDate, на основе которого формируется список дел. Но простое удаление элемента из массива не вариант - после удаления элемента реакт не будет знать, что приложению следует обновиться. Нам нужно сделать массив todoDate частью состояния App и удалять его при помощи метода setState(). Использование этого метода даёт реакту чигнал о том, что произошли какие-то изменения и приложение нужно обновить. Преобразуем App в класс и сделаем todoDate частью его состояния. Было: import React from 'react'; const App = () => {    const todoDate = [     {label: 'Learn JS', important: true, id: 1},     {label: 'Create awesome app', important: true, id: 2},     {label: 'Drink coffee', important: false, id: 3}   ];        return (       <div className="todo-app">       <AppHeader/>       <SearchPa

Собственная система событий

Изображение
При клике по кнопке с значком корзины будем удалять пункт списка. Здесь есть проблема: массив, на основе которого формируется список дел, находится в верхнем компоненте приложения App, а кнопка, при клике по которой должен удаляться элемент массива, находится в компоненте TodoListItem, который, в свою очередь, вложен в компонент TodoList. То есть нам нужно как-то передать событие клика из компонента TodoListItem в TodoList, а оттуда в App. Давайте вспоминать. Когда нам нужно было передать элементу списка событие клик, мы добавили ему свойство onClick в которое передали функцию. export default class TodoListItem extends Component {   render() {     const { label, important = false } = this.props;       return (         <span            className="todo-list-item-label"            onClick = {() => console.log(`${label}`)}>            {label}          </span>             );   }; } Здесь поступаем точно так же, за исключением того, что вместо ст

State - состояние React компонента

Изображение
Классы в React используем в тех случаях, когда нам нужно хранить внутреннее состояние компонента, которое изменяется в ходе выполнения программы. Такое состояние называется State. State очень похоже на Props - свойства, разница только в том, что State можно изменить, а Props - нет. State это всегда объект. Хранить State можно в конструкторе export default class TodoListItem extends Component {      constructor() {     super();     this.state = {       done: false     }   } } Или при помощи полей класса (экспериментальное свойство пока ещё не вошедшее в стандарт). Дополнено:   уже вошедшее export default class TodoListItem extends Component {      state = {       done: false     };  } Напишем код. который позволяет в зависимости от значения  done добавлять к пунктам списка дел отметку о выполнении. Для этого достаточно присвоить им класс  done, для которого в css указаны соответствующие стили. 1. Деструктурируем state const { done } = this.state; 2. Со

Обработка событий

Изображение
Самое базовое событие клик. Добавляется нужному элементу при помощи свойства onClick в которое передаётся функция. export default class TodoListItem extends Component {   render() {   const { label, important = false } = this.props;     return (         <span           className="todo-list-item-label"           onClick = {() => console.log(`${label}`)}>           {label}         </span>     );   }; } Если функция содержит больше одной строки кода, помещать её в JSX нерационально. Попробуем вынести функцию из JSX  внутрь класса. Вот такой код вызывает ошибку TypeError: Cannot read property 'props' of undefined: export default class TodoListItem extends Component {   onLabelClick () {     console.log(`${ this.props. label}`);   }      render() {   const { label, important = false } = this.props;   return (        <span         className="todo-list-item-label"         onClick = {this.onLabelClick}>        

Классы в React

Изображение
Реакт компоненты улобно создавать при помощи функций. const AppHeader = ({toDo, done}) => {   return (     <div className="app-header d-flex">       <h1>Todo List</h1>       <h2>{toDo} more to do, {done} done</h2>     </div>   ); }; Такая функция принимает в качестве параметра объект props, в котором содержатся свойства компонента. Как правило, этот объект сразу же деструктурируется и нужные свойства используются в коде компонентов. Возвращает функция реакт-элемент. Работать с функциями очень удобно. Они компактные, их легко использовать и тестировать. Недостатком функций является то, что у них нет внутреннего состояния. Нам некуда сохранять свойства компонента, которые могут изменяться во время работы программы. Если нам нужен компонент, состояние которого будет меняться во время работы программы, для его создания необходимо использовать класс. В приложении ToDo List таким компонентом могут быть элементы списка

Структура React-приложения Ч2.

В предыдущей части  мы выяснили, что типичным подходом к построению реакт приложения является следующий 1. Один компонент - один файл 2. Все компоненты помещаем в папку components 3. Хорошие компоненты - независимые компоненты В теме про css  сказали, что кроме js файлов в папку  components  помещаем css файлы, что название js и css файлов повторяет название компонентов, только с соответствующим расширением. Но дело в том, что ещё нужно куда-то добавить юнит-тесты, затем какие-то ресурсы, те же иконки. Поэтому в итоге мы приходим к тому, что для каждого компонента нужно создать свою собственную папку. Во всяком случае на больших проектах это устроено именно так. Разумеется, при этом изменяется путь к файлам, который мы прописываем в импорте Если раньше мы писали import AppHeader from './components/AppHeader'; То сейчас это будет выглядеть как import AppHeader from './components/AppHeader/AppHeader'; С целью сокращения пути к папке предлагается внутри

React. Как подключить css

Изображение
Подключаем Bootstrap Проходим по адресу  https://www.bootstrapcdn.com/ Копируем ссылку Complete CSS:  https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css Заходим в папку publiс проекта, файл index.html и добавляем в блок head такой код <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> Подключаем Font Awesome Проходим по адресу:  https://www.bootstrapcdn.com/fontawesome/ Копируем ссылку Font Awesome CSS  https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css Заходим в папку publiс проекта, файл index.html и добавляем в блок head такой код <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> Теперь мы можем в JSX добавлять элементам классы, которые присутствуют в Bootstrap, и элемент будет стилизоваться так, как это предполагают стили Bootstrap. Важно не забывать, что

Массивы как свойства компонентов react

Изображение
Сейчас данные о пунктах списка дел хранит TodoList в свойствах label и important const TodoList = () => (     <ul>       <li><TodoListItem label='Learn JS' important/></li>       <li><TodoListItem label='Create awesome app'/></li>     </ul>   ); Это не совсем правильный подход. Задача списка дел - отображать данные, а получать и хранить их значения и важность лучше в основном файле проекта index.js в компоненте App. При таком подходе, если нам понадобится изменить список дел, не нужно будет искать его по всем файлам проекта, достаточно будет внести изменения в основной файл. const App = () => {    const todoDate = [     {label: 'Learn JS', important: true},     {label: 'Create awesome app', important: true},     {label: 'Drink coffee', important: false}   ];    return (      <div>       <AppHeader/>       <SearchPanel/>       <TodoList todos={todo

Props - свойства компонентов

Изображение
Props от англ. properties - аналоги параметров в обычных функциях JavaScript. Например const MyComponent = props => (    <div> Привет, {props.name} </div>  );  const el = < MyComponent name ="Mark" />  ReactDOM.render(el, document.querySelector('#root')); В таких компонентах очень удобно использовать деструктуризацию const MyComponent = ({name}) => (    <div> Привет, {name} </div>  );  const el = < MyComponent name ="Mark" />  ReactDOM.render(el, document.querySelector('#root')); Чтобы не таскать везде объект props, можно сразу в аргументах разбить его на переменные. Ещё один пример. У нас есть TodoList import React from 'react'; import ReactDOM from 'react-dom'; import TodoListItem from './TodoListItem'; const TodoList = () => {   return (     <ul>       <li><TodoListItem/></li>       <li><TodoListItem/>&