Задать вопрос
  • Как сделать пагинацию в reactjs? (без стороних библиотек для компонентов)?

    rockon404
    @rockon404 Куратор тега React
    rsoinvi, она особо ничем не будет отличаться от пагинации без использования react/redux, за исключением того, что вместо html у вас jsx, а данные сервера будут храниться в store redux.

    Так же нужно чтобы был урл на каждую пагинацию и при перезагрузки, контент должен оставаться таким же

    Придется добавить в проект react-router. Читаете при загрузке страницы query параметры и передаете в запрос. По клику на пагинатор обновляете url и через методы жизненного цикла отправляете запрос.
  • Какой стандарт EcmaScript учить, ES6 or ES5?

    Антон,
    Да как-то странно на собеседовании...

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

    Больше спрашивают про прежний опыт и рассказ о себе.

    На нормальных интервью оцениваются как soft skills, так и hard skills.

    У реактовцев все совсем плохо, да?

    Ad hominem
  • Какой стандарт EcmaScript учить, ES6 or ES5?

    Антон, в странные места вы собеседовались. Не было в моей жизни технического интервью на Frontend Developer, где бы не было вопросов и задач на знание JavaScript.
  • Зачем в JS постоянно возвращают функции которые возвращают значения?

    vs1710, ну примеры бывают очень сложные для понимания на первый взгляд.
    Например есть такая интересная библиотека для React StyledComponents. Она создает React компоненты, генерирует для них классы и добавляет css код на страницу:
    import styled from 'styled-components';
    
    const Wrapper = styled.div`
      max-width: 1200px;
      margin: 0 auto;
      padding: 0 16px;
    `;


    styled.div это функция которая принимает шаблонную строку как массив интерполяций(звучит сложно, но это как-то так). Она детектит в этом массиве функции и выполняет их передавая переменные из свойств компонента и опционально контекста React через компонент Provider(например можно передать в Provider тему, сведения об устройстве или еще что-нибудь и styled будет получать их из контекста).

    И вот задача, я хочу добавить стили только для мобильных, не прибегая к использованию нативных медиазапросов, а используя сведения об устройстве которые я передал при инициализации. Пишу такой модуль, который будет использовать хелпер css из библиотеки styled-components для возврата массива интерполяций:
    import { css } from 'styled-components';
    
    const createMediaByConditionFn = conditionFn => (arg, ...args) =>
      props => conditionFn(props) && css(arg, ...args);
    
    const mobile = createMediaByConditionFn(props => props.device.isMobile);
    const desktop = createMediaByConditionFn(props => !props.device.isMobile);
    
    const media = {
      mobile,
      desktop,
    };
    
    export default media;


    Теперь я могу писать стили для мобильных так:

    import styled from 'styled-components';
    import { media } from 'app-lib';
    
    const Wrapper = styled.div`
      max-width: 1200px;
      margin: 0 auto;
      padding: 0 16px;
    
      ${media.mobile`
        padding: 0 8px;
      `}
    `;


    Этот конкретный вызов media.mobile возвращает эквивалент функции:
    props => (props => props.device.isMobile)(props) && css`padding: 0 8px;`;


    функция выполнится при вызове styled.div c передачей туда объекта props и если props.device.isMobile будет равно true, то мы получим результат вызова css и мобильные стили будут добавлены на страницу, в противном случае получим false и библиотека его просто проигнорирует.

    Мне не надо использовать никаких глобальных переменных(что неправильно и может привести к багам если используется Server Side Rendering) и не надо передавать device по всем компонентам и везде писать проверки.
    Получается лаконично и красиво. А в случае если мы поменяем реализацию определения устройства, то ничего кроме двух функций аргументов передаваемых в вызов createMediaByConditionFn переписывать не придется.
    Пример конечно сложный, зато жизненный.)
  • Зачем в JS постоянно возвращают функции которые возвращают значения?

    Смотрите, есть функция:
    const createWithVAT = vat => price => price + price * vat / 100;

    Если заменим стрелочные функции на обычные получим:
    const createWithVAT = function(vat) {
      return function(price) {
        return price + price * vat / 100;
      }
    }


    После вызова:
    const currentVAT = VAT_RATES.GB; // 20
    const withVAT = createWithVAT(currentVAT);

    withVAT можно представить как функцию:
    price => price + price * 20 / 100;

    или с заменой стрелочных функций на обычные:
    function(price) {
      return price + price * 20 / 100;
    }


    Вот и вся магия. Мы получаем функцию withVAT в которой уже задано значение VAT и можем ее использовать.

    Пример, конечно, притянут за уши, но он очень хорошо демонстрирует механику.
    В случае ООП подхода можно просто держать текущее значение VAT в поле экземпляра/объекта/компонента:
    {
      vat: 20,
      setVat(vat) {
        this.vat = vat,
      },
      calculatePriceWithVAT(price) {
        return price + price * this.vat * 100,
      }
    }


    Еще погуглите классический пример с замыканием и счетчиком.
  • Зачем в JS постоянно возвращают функции которые возвращают значения?

    vs1710, в таком случае могу только посоветовать изучать JavaScript последовательно по учебнику и учиться анализировать и понимать чужой код.
    Это очень простой пример. Возврат функции очень распространенный и эффективный прием в современной фронтенд разработке. Часто возвращаемые функции принимаются как аргумент другими функциями. Чтобы это хорошо понимать нужен определенный уровень подготовки и хорошие знания механики и возможностей языка.
  • Как изменить state checkboxa через props для конкретного елемента?

    rockon404
    @rockon404 Куратор тега React
    JasonJon, есть хорошая поговорка "Когда нет внятного ТЗ, тогда и результат ХЗ". Подходить к решению задачи надо исходя из требований. Судя по вашему примеру и вопросу, вы знаете сколько у вас checkbox элементов и каких. Ответ вы получили в рамках вопроса и своего примера.

    Если не знаете сколько у вас и каких элементов, то тут можно после загрузки данных мапить данные о состоянии в state и так же по данным генерировать форму. Так же можно воспользоваться одним из множества готовых решений.
  • Как изменить state checkboxa через props для конкретного елемента?

    rockon404
    @rockon404 Куратор тега React
    JasonJon, как вариант писать одни данные в разные ключи состояния после загрузки:
  • Почему babel-preset-env не работает?

    rockon404
    @rockon404 Куратор тега React
    Лучше stage-0 сразу поставить
  • Как изменить state checkboxa через props для конкретного елемента?

    rockon404
    @rockon404 Куратор тега React
    JasonJon, если формат данных заранее известен то можно так.
  • Что делать с данными?

    rockon404
    @rockon404 Куратор тега React
    webe, нет handleChange из моего примера тоже внутри зеленого, туда пробрасывается this.props.onChange.
    <MegaDatePicker name="some_date" value={some_date} onChange={this.handleChange} />

    Вот примерный хандлер красного:
    handleChange(event) {
        const { target } = event;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const { name } = target;
    
        this.setState({
          [name]: value,
        });
      }

    Он общий для текстовых полей и этого пикера. По возможности можно еще и именнованные чекбоксы обрабатывать
  • Что делать с данными?

    rockon404
    @rockon404 Куратор тега React
    webe, я бы сделал для календаря все эти ханлеры во внутренней реализации и выносил из него в onChange дату в одном формате.
    <MegaDatePicker name="some_date" value={some_date} onChange={this.handleChange} />

    в onChange он должен передавать:
    {
      target: {
        name: 'some_data', // значение this.pops.name
        value: '12-12-18',  // дата в нужном формате
      },
    }


    Причем в интерфейс можно передавать функцию formatter. То есть без нее возвращается не форматированная дата. Если она передана возвращается вызов функции formatter с передачей ее значения.
    Это если дата может понадобиться в разных форматах.

    В итоге как-то так должно работать:
    componentDidUpdate(prevProps, prevState) {
      if (prevState.selectedDay !== this.state.selectedDay) {
        this.handleChange(this.state.selectedDay);
      }
    }
    
    handleChange = value => {
      const { formatter, onChange } = this.props;
    
      if (formatter) {
        value = formatter(value);
      }
    
      onChange({
        target: {
          name,
          value,
        },
      });
    };


    Если formatter не нужен, не добавляйте.
  • Вопросы по React'y / Redux'y?

    rockon404
    @rockon404 Куратор тега React
    AlexKindGeek, да. В зависимости от требований реализации бывают очень разные.
    Например, где-то это асинхронные запросы во время ввода с проверкой свободного имени пользователя. А где-то валидация на onBlur. Где-то надо еще кнопку Submit валидировать, чтобы все красиво было.
    Думаю вам стоит попробовать на каком-нибудь codesandbox написать форму с конкретными требованиями своими силами и параллельно с использованием formik или redux-form ну и использовать тот вариант который больше понравится/подойдет.
  • Вопросы по React'y / Redux'y?

    rockon404
    @rockon404 Куратор тега React
    AlexKindGeek,
    типичный небольшой редьюсер
    import { fromJS } from 'immutable';
    import { LOGOUT } from "../constants/auth";
    import {
      GET_SETTINGS,
      GET_SETTINGS_SUCCEEDED,
      GET_SETTINGS_FAILED,
      PUT_SETTINGS_SUCCEEDED
    } from "../constants/settings";
    
    const initState = fromJS({
      isFetching: false,
      isError: false,
      data: null,
    });
    
    export default function settings(state = initState, action) {
      const { type, payload } = action;
    
      switch (type) {
        case LOGOUT:
          return initState;
        case GET_SETTINGS:
          return state.set('isFetching', true);
        case GET_SETTINGS_SUCCEEDED:
          return state.set('data', fromJS(payload)).set('isFetching', false);
        case PUT_SETTINGS_SUCCEEDED:
          return state.merge({ data: payload });
        case GET_SETTINGS_FAILED:
          return state.set('isFetching', false).set('isError', true);
        default:
          return state;
      }
    }

    Когда много форм лично я не использую ни formik, ни redux-form.
    state = {
      firstName: '',
      lastName: '',
      sex: '',
      addressLine1: '',
      addressLine2: '',
      country: '',
      zipIndex: '',
      errors: {},
    };

    Не вижу ничего не читаемого, даже если бы полей было еще больше.
    Если получаете состояние по props и не знаете какие будут поля можно делать так:
    state = computeDerivedStateOnProps(this.props);
    и в вызове computeDerivedStateOnProps мапите данные в состояние.

    Если вам удобно работать с этими библиотеками и они подходят под ваши требования, то почему бы и нет.
    Но самому хранить состояние форм в redux не стоит.
  • Что делать с данными?

    rockon404
    @rockon404 Куратор тега React
    webe, почему ваш DatePicker возвращает значения в разных форматах в разных случаях?
    Почему преобразования происходят не внутри него?
    В идеале его можно было бы обрабатывать одним хандлером с селектами, инпутами, именнованными чекбоксами и прочим.
  • Что делать с данными?

    rockon404
    @rockon404 Куратор тега React
    webe, а почему ваш DatePicker не может возвращать FakeEvent в одном формате?:
    {
      target: {
        name,
        value, 
      },
    }

    и иметь интерфейс:
    <DatePicker name="date" value={date} />

    Для чекбоксов если имена неизвестны придется писать отдельный handler:
    handleCheckboxChange = e => {
        const checkboxes = xor(this.state.checkboxes, [e.target.value]);
    
        this.setState({ checkboxes });
      }


    xor - удобный хелпер из lodash.