Ответы пользователя по тегу JavaScript
  • Как построить график?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    -1) нужно разобраться с большим количеством вопросов по теории разработки и основам языка. (пока опустим)
    по делу:
    0) нужно выбрать библиотеку для отрисовки графиков.
    1) нужно приготовить данные для этой библиотеки
    2) нужно отрисовать компонент из библиотеки с графиками и туда передать в качестве props данные.

    Окей, разберемся подробнее:
    0) допустим это https://github.com/jerairrest/react-chartjs-2
    Какой план работ? Идем по ссылке на гитхаб, там видим, что это лишь "реакт-обертка" для библиотеки - www.chartjs.org/docs/latest - отлично! Смотрим документацию, видим следующий пример:

    var myChart = new Chart(ctx, {
        type: 'bar', // тип диаграммы
        data: { // ДАННЫЕ
            labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], // МЕТКИ - здесь ваши AF, AX, AL ... в массиве
            datasets: [{
                label: '# of Votes', 
                data: [12, 19, 3, 5, 2, 3], // ДАННЫЕ - здесь ваши "количество говорящих" - 652230, 1580, 28748.. - так же в массиве и в том же порядке.
                backgroundColor: [ // настройки цветов... и значения остальных пунктов, так же можно найти в документации.
                    'rgba(255, 99, 132, 0.2)',
                    'rgba(54, 162, 235, 0.2)',
                    'rgba(255, 206, 86, 0.2)',
                    'rgba(75, 192, 192, 0.2)',
                    'rgba(153, 102, 255, 0.2)',
                    'rgba(255, 159, 64, 0.2)'
                ],
                borderColor: [
                    'rgba(255,99,132,1)',
                    'rgba(54, 162, 235, 1)',
                    'rgba(255, 206, 86, 1)',
                    'rgba(75, 192, 192, 1)',
                    'rgba(153, 102, 255, 1)',
                    'rgba(255, 159, 64, 1)'
                ],
                borderWidth: 1
            }]
        },
        options: { // ЕЩЕ опции, тоже значения опций в документации, можно просто опустить.
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero:true
                    }
                }]
            }
        }
    });


    Так же, почти у всех настроек есть значения по умолчанию, поэтому большинство из них можно опустить.

    2) отрисовка компонента - это уже нужно смотреть в документации реакт-обертки:
    import {Doughnut} from 'react-chartjs-2'; // отрисует Doughunt диаграмму, вам наверняка нужны Line или Bar
    
    <Doughnut data={...} /> // а вот и сама отрисовка, это нужно сунуть в ваш div, где в data должен быть объект*


    2.5) разжую про объект:
    const myData = { // минимальный пример
    labels: ["AF", "AX", "AL"], // МЕТКИ - здесь ваши AF, AX, AL ... в массиве
    datasets: [{
        label: '# of Votes', 
        data: [652230, 1580,28748], // ДАННЫЕ - здесь ваши "количество говорящих" - 652230, 1580, 28748.. - так же в массиве и в том же порядке.
    }]
    }


    Итого ваш рабочий пример с "жестко записанными данными":
    import {Bar} from 'react-chartjs-2';
    ...
    render() {
     const myData = { // минимальный пример
       labels: ["AF", "AX", "AL"], // МЕТКИ - здесь ваши AF, AX, AL ... в массиве
       datasets: [{
        label: '# of Votes', 
        data: [652230, 1580,28748], // ДАННЫЕ - здесь ваши "количество говорящих" - 652230, 1580, 28748.. - так же в массиве и в том же порядке.
       }]
      }
     return (
        <div><Bar data={myData} /></div>
     )


    само собой разумеется, что вам нужно вместо жестко описанной myData формировать переменную на основе тех данных, что вы получили от сервера и записывать ее в state, а в компоненте из state считывать. Тогда при получении новых данных от сервера будет происходить перерисовка.
    Ответ написан
    Комментировать
  • Построение графика axios+react, как лучше сделать?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Доброе утро.

    1) из данных формируете новый "слепок" значений: язык + кол-во говорящих (например: { ru: 1000, en: 2000 } или [1000, 2000] + словарик ['ru', 'en'] )
    2) наносите это на график, например, используя react-chartjs2
    Ответ написан
  • Как правильно обновить комонент в react + redux?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Чтобы изменить один компонент из другого, нужно либо достучаться до общего родителя и спустить props вниз, либо использовать redux (который делает тоже самое по сути).

    В вашем случае, нужно через экшен из Х что-то изменять в том редьюсере, на который подписан ваш ChangeMe.

    > нужно добавить проверку в компоненте ChangeMe не изменились ли параметры
    lifecycle метод componentWillReceiveProps вам поможет

    > но есть ситуации когда его нужно обновить даже когда парамерты не изменились
    эту ситуацию описать внутри componentWillReceiveProps в обычном if условии.
    Ответ написан
  • Есть ли разница, если использовать в React между, ()=> и this.bind(this)?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    лучше писать в constructor() чем в render(). т.к bind будет происходить каждый рендер (onClick = {this.func.bind(this))

    Именно так и есть. То есть "уйдет больше памяти" , так как она будет расходоваться из-за постоянного определения новых (анонимных () => {...} ) функций.

    Еще можете использовать плагин для babel: transform-class-properties и тогда сможете писать сразу так:
    class BlaBla extends React.Component {
      myFuncWIthThis = () => {
         ....
      }
      render() {
        <button onClick={this.myFuncWithThis}>Click me</button>
      }
    }
    Ответ написан
    4 комментария
  • Redux-Store Best practice: как лучше в store разделять данные от состояния UI?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Состояние интерфейса обычно хранится в state компонента.
    - экраны в связке с роутингом (тут и состояние хранить обычно не нужно дополнительно, так как оно уже хранится в роуте (объект location))
    Ответ написан
  • Какой из способов определения клика лучше использовать на практике при построении React приложения?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    ‘повешевания’ события через onchange непосредственно на сам элемент
    Ответ написан
  • Где можно консультироваться по JS у профи?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    По реакту/js могу проконсультировать.

    Либо на codementor.io
    ссылка не вставляется нормально:
    https://www.codementor.io/experts?q=javascript&lang=russian


    p.s. неоднократно уже задавался такой вопрос (линк)
    Ответ написан
    Комментировать
  • Что можете посоветовать для графиков в React?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    есть достаточно простой и кастомизируемый (не сильно) компонент: react-chartjs-2
    Ответ написан
    Комментировать
  • Как предотвратить отправку формы при выборе локации в react-google-places-suggest?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Возможно, у формы есть onSubmit событие. Удалите его, и сделайте отправку формы только по onClick на кнопку отправки.
    Ответ написан
  • Как вносить правки в скачанные через npm плагины и модули?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Залезли правильно, почитайте еще readme как собрать этот пакет. Наверняка, автор держит шаблон в одном месте, а итоговая "библиотека" собирается в один файлик. Поэтому вам нужно "сбилдить" этот проект, внеся изменения в template.

    Как сказали выше, когда вы (или кто-то другой) попробует скачать этот модуль из npm изменения потеряются. Поэтому вы можете либо сделать форк и указать в package.json ссылку на свой репозиторий, либо (если функционал хорош) сделать форк и отправить пул-реквест автору.
    Ответ написан
    1 комментарий
  • Как настроить HMR стилей в webpack 3?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    {
      test: /\.scss$/,
        use: [
            'style-loader',
            'sass-loader', // поменять местами с css-loader
            'css-loader' // поменять местами с sass-loader
        ]
    },


    Простыми словами так: сначала scss код проходит через sass-loader, потом этот код проходит через css-loader, и это все потом впихивается в style через style-loader. Порядок снизу вверху.
    Ответ написан
    Комментировать
  • Зачем нужен del-cli w webpack?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    В каталоге dist может быть много всего. В том числе какие-то старые скопированные файлы, которые могут помешать / быть не нужны в новом билде (что более вероятно). Поэтому почистить каталог перед созданием новых файлов - не плохая идея.

    Например, вы разбиваете свой большой бандл на кусочки.
    У вас в момент билда получилось 30 кусков.
    Затем вы удалили какой-то код, и вот у вас уже 29 кусков. Они заменятся все внутри dist, но 30й останется.

    А если у вас еще было наименование по типу: имя + хэш / или что либо другое - то у вас в dist будет просто куча хлама.
    Ответ написан
    Комментировать
  • Как правильно удалять нужный элемент из массива?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Так как вам всегда нужно возвращать новый массив, задачу можно разделить следующим образом:
    1) в новый массив копируете* все с начала до index
    2) в этот же новый массив копируете все с index+1 до конца

    * - для копирования отлично подходит spread operator. В теории выглядит так:
    const arr = [{a:1},{b:2},{c:3},{d:4}]
    //допустим, вы прислали index 1 и сохранили его в переменную index, например
    const newArr = [
      ...arr.slice(0, index), // клонируем все элементы до индекса
      ...arr.slice(index+1), // клонируем все элементы после индекса
      // итого: индексный элемент удален
    ]


    Хазрат Гаджикеримов вам верно подсказал так же про filter. В комментарии привел верное решение. Давайте теперь рассмотрим ваше:
    if(action.type === 'REMOVE_STUDENT') {
            let newArr = state; // сохранили в newArr ссылку(!!!) на старый массив. Если вы хотели скопировать массив, то нужно было писать: let newARr = [...state] (если в state просто массив)
            newArr.splice(action.payload, 1); // здесь вы из newArr ( и из state, так как сохранили ссылку) удалили с ИНДЕКСА один элемент. Так же, внимание, вы используете sPlice, а не slice. Разницу нужно уточнить! (подсказка ниже как)
            return newArr.filter(element => element !== action.payload); // а здесь вы что вообще написали? вы сравнили element (что там? объект?) с action.payload (в которой как вы говорите индекс). Что должно быть в итоге? ;)
        }


    Очень легко гуглить все незнакомые функции по типу: name MDN
    в вашем случае запросы в гугл:
    slice MDN (первая ссылка выдачи)
    filter MDN (первая ссылка выдачи)

    Теория из-за которой не происходит понимания: копирование объектов по ссылке
    Ответ написан
    2 комментария
  • Что почитать/посмотреть по тестированию кода (JS)?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Сначала легко запутаться. Мне помогло следующее:
    1) есть тест-раннеры (то есть утилиты, которые запускают тесты, в вашем вопросе это mocha) и библиотеки "ассеротов" - это что-то типа "утверждений", которые вы в тестах будете использовать.
    2) все unit тесты, это не что иное как тестирование какой-то функции на то, что она выдаст заранее описаный (вами!) результат. Образно: есть функция sum(a,b), вы пишите какой-то такой код:
    import { sum } from './my-functions'
    ожидаю, что sum(1,3) === 4


    если добавить какую-нибудь псевдо-библиотеку ассертов, будет примерно так:
    import { sum } from './my-functions'
    import { should } from 'another-assert-library' // should в переводе "быть/являться" 
    ожидаю, что sum(1,3).should.be.eql(4) // ожидаю что sum(1,3) будет равно 4


    На хабре из последнего про mocha, перевод статьи со "скотча", в которой, по-моему код уже устарел, и тесты скорее всего не пройдут, но ознакомиться можно.

    Не остался в стороне и learn.javascript.ru с его разделом про тесты
    Ответ написан
    Комментировать
  • Где найти примеры очень сложных работ на Javascript/React/Angular/Vue?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    А кто, собственно, захочет выкладывать в опен-сорс решения для коммерческих организаций? Это же занимает время. Нужно все приготовить, подчистить, задокументировать где не хватает, тесты дописать. Это куча работы, кому за это заплатят? Какой прок от этого организации (повышение доверия к организации - как вариант, но далеко не всем это нужно)? Придется объяснять, что это за продукт, и что он делает. Почему применены такие-то костыли и как с этим жить. Бррр... там работы много. Не нужной для организации работы.

    Так же многие компании просто не хотят раскрывать как они сделали ту или иную фичу. Опять же - зачем?Конкурентов плодить? ;)

    В то же время, большие опен-сорс решения все же имеют место быть (но у них изначально опен-сорс как фича, или компания хочет таким образом привлечь к себе внимание. Либо компания может себе это позволить). Обычно, они сразу и всем известны, и гугляться на раз-два-три, типа react open source projects, angular open source projects и тд.
    Ответ написан
    Комментировать
  • Как использовать пакет prop-types?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Вероятнее всего, предупреждение в том, что вы пишите React.PropTypes...
    А нужно просто PropTypes...
    Например:
    import React, { Component } from 'react'
    import { PropTypes } from 'prop-types' // можно и import PropTypes from 'prop-types'
    ... 
    ComputersList.propTypes = {
      data: PropTypes.shape({
        rows: PropTypes.array.isRequired,
        isFetching: PropTypes.bool.isRequired,
      }).isRequired,
      onlineSessions: PropTypes.array.isRequired,
      onChangeSort: PropTypes.func.isRequired,
    }
    Ответ написан
    Комментировать
  • Как правильно тестировать Reducer в Jest?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    it(`handle action ${patientActions.ON_CHANGE_PATIENT}`, ()=>{
            expect(reducer(undefined, {
                type: patientActions.PATIENT_INIT_STATE, // тут должно быть patientActions.ON_CHANGE_PATIENT
                payload: {
                    value: '11122',
                    field: 'patient_ur'
                }
            })).toEqual({...defaultStates, patient_ur: '11122'})
        })


    ошибку в этом тесте исправьте, если "пройдет", то думаю дальше все получится. Суть юнит-тестов в том, что вы пишите: было А, применил какую-то функцию (в вашем случае редьюсер), стало Б. Сравнить с В.
    Причем "В" вы описываете сами.
    Ответ написан
  • Когда действительно необходимо потащить flow в проект?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Для того, чтобы в проекте что-то появилось, обычно возникают такие ситуации:
    1) у меня все работает, но что-то не устраивает
    2) у меня есть время и желание выучить новое

    Если у вас п.2 - то просто берете flow и проверяете стало ли с ним лучше / удобнее. Если да - можно внедрять.
    Если п.1 - анализируете что может вам помочь в работе, и пробуете разные инструменты.
    Ответ написан
    Комментировать
  • Как подключить less к Webpack?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Webpack 2/3 ?

    ...
    const ExtractTextPlugin = require('extract-text-webpack-plugin');
    ...
    // в секции plugins
    plugins: [
    ...
    new ExtractTextPlugin({
          filename: 'style-[contenthash].css',
          disable: false,
          allChunks: false, // true
        }),
    ...
    ]
    
    в секции module -> rules (loaders)
    ...
    {
            test: /\.less$/,
            loader: ExtractTextPlugin.extract({
              fallbackLoader: 'style-loader',
              loader: ['css-loader', 'less-loader'],
              publicPath: '/public', // ваш publicPath
            }),
          },
    Ответ написан
    9 комментариев
  • Универсальный fetch, очень большое количество запросов, с разными условиями, как написать правильно?

    maxfarseer
    @maxfarseer
    https://maxpfrontend.ru, обучаю реакту и компании
    Не вникая в код, в логику и так далее, просто если взять за должное, что вы должны один Action creator (или для удобства, просто "экшен") запускать после результата другого, то тут важное правило лишь одно: экшен должен быть вызван внутри функции dispatch - и все будет ок. Главное, чтобы экшен "не выпал" из потока экшенов идущих через диспетчер, в таком случае он обязательно попадет в редьюсеры и все будет как надо.

    p.s. судя по вашему коду вы так и делаете. Если будет удобно разбивайте функцию на более мелкие повторяющиеся кусочки и т.д. (но вижу, что и это уже тоже делаете).
    Ответ написан
    2 комментария