• Как создать на React корзину?

    Вообще, вопрос вы задали достаточно интересный. Однако проблема в том, что ответ на него достаточно массивный, если конечно отвечать полностью.

    Потому, к сожалению, придётся немного сократить.

    Представим, у вас есть небольшой магазин, где присутствует несколько товаров. Например, это будут простые телефоны. Структура одного товара довольно простая: картинка, название, описание и кнопка купить.
    Под капотом всё обстоит немного иначе. У нас будет массив, внутри которого есть объекты с данными. В объект будет входить: название продукта, описание продукта, картинка на продукт и уникальный идентификатор. Пример одного объекта будет немного ниже.

    {
      id: 0,
      name: "Nokia 3310",
      description: "Телефон, переживший падение в жерло вулкана",
      url: "https://static.shiftdelete.net/wp-content/uploads/2018/05/nokia-3310-1-milyon-volt-yuke-dayandi-sdn-01.jpg",
      price: 2800
    }


    Поскольку React приложения являются одностраничными, потому-то и называются SPA, что в переводе на нормальный “single page application”. У нас будет несколько страниц: первая страница с продуктами, где можно приобрести какой-то товар, а вторая страница — это простая корзина.

    Думаю, с роутингом проблем не должно возникнуть. Однако, если те возникнут, можете посмотреть это видео. На английском, на русском.

    Теперь определимся.

    При нажатии на кнопку «Купить» должно произойти действие. Продукт, который мы купили должен попасть в корзину, а при переключении на страницу корзины показываться на странице. Возникает вопрос, как это сделать?

    Ответ довольно простой: создать пустой массив, в который мы и будем скандировать все купленные продукты. И именно данный массив и будет отображаться на странице корзины. Объект купленного продукта будет, например, таким.

    {
      id: 0,
      name: "Nokia 3310",
      description: "Телефон, переживший падение в жерло вулкана",
      url: "https://static.shiftdelete.net/wp-content/uploads/2018/05/nokia-3310-1-milyon-volt-yuke-dayandi-sdn-01.jpg",
      price: 2800,
      count: 1
    }


    На странице у нас будет несколько кнопок. Первая отвечает за удивление продукта из корзины, вторая за добавление ещё одного товара, и последняя за удаление одного товара. При каждом нажатии, мы будет обращаться к массиву с объектами и искать нужный элемент. Если он есть, то при покупке, изменять его count, добавляя один. Как это будет происходить?

    Расскажу про алгоритм добавления элемента в массив:
    1. При нажатии, мы будет получать его идентификатор.
    2. Затем проходимся по массиву через цикл find получаем сам объект.
    3. В конце записываем полученный объект в массив. (P.S. Запомните одно важное правило, поскольку в React или Redux нельзя изменять состояние, использовать push следует крайне осторожно. В данном случае использовать push не стоит, пригодиться spread-оператор).


    Хоть и написал в ответе, продублировать здесь лишним не будет. Утром не смог добавить пример. Однако, исходя из вашего изначального вопроса о магазине, написал простенький пример.

    Скажу сразу, повторение кода в примере сознательное. Если будете делать нечто такое самостоятельно, избегайте повторение кода, поскольку это может повлиять на поддержку приложения. Да и вообще, повторять код не есть хорошо, если тот конечно не сознательно повторённый.

    Сам пример: CodeSandbox (Cart)
    Ответ написан
    8 комментариев
  • Почему функция addTask() не работает?

    Здравствуйте!
    Надеюсь, я правильно смогу объяснить почему ваша функция не работает.
    Во-первых, следует понять, что нужно сделать в функции:
    1. Получить текущее значение в input
    2. Создать разметку для нового таска, где важный элемент – текст из input
    3. Вставить новый элемент в ul. list_task и очистить input


    Если вы присмотритесь к вашему коду, найдётся несколько проблем, одна из которых, из-за чего в общем-то у вас функция не работает должным образом — это перезапись.

    Когда новый элемент добавляется, активируется функция addTask.

    1. Внутри вы получаете значение, находящееся внутри input
    2. Создаете переменную и присваиваете ей list_taskEl куда в свою очередь записываете разметку нового элемента с текстом. Таким образом, даже если вы уберёте list_taskEl.appendChild(task) всё будет работать. Но не так, как вы хотели бы.


    Возникает вопрос, что делать? Ответ таков: следует переработать код в самой функции addTask, пропуская лишь строчку, где получаете значение.

    Чтобы сразу не давать ответ, как вообще можно это решить, я оставлю вам ссылку на интересную статью, которая поможет: insertAdjacentHTML.

    Ниже под Spoiler оставлю, как я переработал ваш код. На случай, если всё же захочется посмотреть

    Spoiler
    //создание задачи по нажатию на клавишу интер
    document.addEventListener('keydown', (event) => {
      if (event.code === "Enter") {
        addTask();
        clearInput();
      }
    })
    
    //функция очистки инпута
    function clearInput() {
      input_taskEl = document.getElementById('input_task').value = "";
    }
    
    const templateTask = (text) => {
      return `
        <li class="task">
          <h2 class="task__title">${text}</h2>
          <div class="task__buttons">
            <button class="task__button><i class="fa fa-edit"></i></button>
            <button class="task__button><i class="fa fa-close"></i></button>
          </div>
        </li> 
      `
    }
    
    const addTask = () => {
      const input_taskEl = document.getElementById('input_task').value;
    
      const template = templateTask(input_taskEl);
    
      list_taskEl.insertAdjacentHTML('beforebegin', template);
      clearInput();
    }
    Ответ написан
    2 комментария
  • Объясните, как действует код и почему он работает: weirdReverse=a=>a.sort(n=>1)?

    KaizDA
    @KaizDA Автор вопроса
    Прочитал одно из возможных объяснений в обсуждении. Поскольку в английском не слишком хорош, могу сделать ошибки. По этой причине, пожалуйста, если был где-то не прав, поправьте, буду благодарен. Ссылка на то, где мной это было прочитано.

    В основе своём метод sort(), как уже понятно из названия сортирует массив элементов. При сортировке букв он используется порядок UTF-6, именно по потому он может сортировал от А до Я, предварительно вызывая String для преобразования элементов массива в строку (то же самое происходит и с числами). Исходя из вышеперечисленного, метод sort() сортирует элементы исходя из Unicode. Для сортировки чисел в метод передаётся аргументы, которые очень часто называется (a, b), где проходит сравнение, что => a - b.

    В случае с заданием, нам приходится сократить код и использовать только один знак, в моём случае это n. Почему же код действует? Как я понял это происходит потому, что компаратор (как я понял из одного из ответов на просторах в интернете, компаратор – это метод класса, который реализует сравнение объектов, признаки равенства и неравенства коего определяет тот, кто этот класс создал), использует тот факт, что его аргументы передаются слева-направо, из-за чего для многих массивов порядок сортировки такой: [‘A’, ’B’, ’C’, ’D’] => A> B> C> D, что собственно, логично. Следовательно, при перестановке в порядке возрастания – это фактически разворот (этот момент не совсем был мной понят).

    Однако, нечто подобное будет работать только для массивов с длиной менее одиннадцать, так как NodeJS переключает алгоритм сортировки для разных размеров массива, хотя это также используется и в других языках (стоит заметить, человек, написавший последнее, не проверял V8, чтобы подтвердить это).
    Можно даже сказать, что подобного рода реализация ошибочна, поскольку кроме как в CodeWars код не работает от слова совсем и он вообще не должен был работать. Таким образом, более-менее вероятный ответ – это допущение в NodeJS.
    Ответ написан
    5 комментариев