• Нормально ли написаны компоненты??

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. formatTime - хелпер, я не буду таратить время на анализ качества его реализации, скажу лишь, что в компоненте ему не место. Перенесите в папку lib, utils или как там она у вас называется, импортируйте где нужен и используйте.

    2. Закроем, пока глаза на пункт 1. formatTime у вас написан стрелочной функцией, но он никуда не передается и в нем не используется ключевое слово this - определять его стрелочной функцией было бессмысленно. Изучите вопрос и постарайтесь понять зачем их используют.
    spoiler
    привязка контекста

    То же с getChatsUser - функция никуда не передается.

    3. Никогда не используйте тернарки если, альтернативный кейс null. Замените на:
    render() {
      /* ... */
      const hasUnreadMessages = unread_amount > 0;
      
      return (
        <div>
          {hasUnreadMessages && (
            <div className="unread-message-container">{unread_amount}</div>
          )}
        </div>
      );
    }


    4. Зачем передаете в mapStateToProps все состояние редьюсера? Передавайте только необходимые компоненту данные:
    export const userDataSelector = state => state.chatReducer.userData;

    const mapStateToProps = state => ({
      userData: userDataSelector(state),
    });

    Селекторы очень полезная вещь. В реальных приложениях они часто помногу раз переиспользуются и в случае изменения структуры store, вам придется изменить только селекторы, вместо изменения реализаций mapStateToProps по всему приложению. Так же, они, зачастую, короче.

    Почитайте про библиотеку reselect.

    5. Вместо:
    const query = Object.assign({}, params, { per_page });

    лаконичней и проще для анализа:
    const query = { ...params, per_page };

    6. Правильное обновление состояния на основе предыдущего:
    this.setState(prevState => ({
      per_page: prevState.per_page + 5,
    }));


    7. Использование trailing comma - очень хорошая практика, советую ей не пренебрегать.

    8. Более оптимизированным вариантом для списков, будет вместо определения стрелочных функции в элементах каждый render:
    <div onClick={() => setUserForChat(userData)}>
    использовать data-атрибуты:
    <div data-id={userData.id} onClick={setUserForChat}>

    Реализацию setUserForChat придется изменить:
    setUserForChat = e => {
      const { id } = e.target.dataset;
      // some code with using id
    }
    Ответ написан
    2 комментария
  • ООП + React + typescript как правильно создавать компоненты?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Я так пишу:
    import * as React from 'react';
    import { connect, DispatchProp } from 'react-redux';
    import { connectedPropSelector } from './selectors';
    
    interface OwnProps {
      ownProp: string,
    }
    
    interface ConnectedProps {
      connectedProp: string,
    }
    
    type Props = OwnProps & ConnectedProps & DispatchProp<any>;
    
    interface State {
      someKey: string,
    }
    
    class Example extends React.Component<Props, State> {
      state = {
        someKey: 'someValue',
      };
      
      render() {
        const { ownProp, connectedProp } = this.props;
    
        return ( /* ... */ );
      }
    }
    
    const mapStateToProps = state => ({
      connectedProp: connectedPropSelector(state),
    });
    
    export default connect(mapStateToProps)(Example);


    Официальная документация
    Ответ написан
    1 комментарий
  • Как деструктуризировать аргументы функции?

    rockon404
    @rockon404
    Frontend Developer
    const AnswerItem = ({ onAnswerClick, answer: { id, text } }) => ...

    Но лучше проверять существование объекта answer, если конечно не уверены точно, что он будет передан в любом случае.
    Ответ написан
    1 комментарий
  • Что такое изоморфное приложение и как его создать?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Почитайте любую тематическую статью на эту тему.
    1. В самом простом случае у вас две точки входа server(с ReactDOMServer.renderToString) и client(c ReactDOM.hydrate).

    2. State можно получать на сервере и передавать на клиент, примерно, так:
    <script>window.__INITIAL_STATE__ = json.stringify(initialState);</ script>

    В configureStore:
    export = function (initialState: {} = {}) {
      if (__CLIENT__) {
        initialState = JSON.parse(JSON.stringify(window.__INITIAL_STATE__));
      }
    
      return createStore(combineReducers({ ...rootReducer }), initialState, enhancer);
    }

    3. Никаких глобальных переменных для состояний изменяющихся от клиента к клиенту(локали, темы и прочее). Node обрабатывает множество запросов одновременно и информация клиентов при передаче конфигураций в глобальные модули или при использовании глобальных состояний может перемешаться.
    4. Получение данных на сервере и клиенте тот еще головняк. Посмотрите как реализована библиотека react-frontload.
    Ответ написан
    Комментировать
  • Не распознаёт jsx, когда добавляю package.json, как лечить?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    ...но если кладу этот файл в отдельную папку и рядом с файлом создаю файл package.json с таким содержанием...

    Зачем?

    Срочно изучайте основы npm и wepack.

    Если хотите собирать бандл из другой директории измените путь в свойстве entry конфига webpack:
    module.exports = {
      entry: './path/to/my/entry/file.js'
    };

    package.json добавлять не надо, этот файл для других целей.
    Ответ написан
    2 комментария
  • Как убрать ошибку Uncaught ReferenceError?

    rockon404
    @rockon404
    Frontend Developer
    Вы вы используете в коде неопределенный идентификатор onAjaxSucces и получаете соответствующую ошибку.
    Вы должны определить в коде выше функцию onAjaxSucces
    function onAjaxSucces(data) {
      // do something with data
    } 
    
    $.post(
      "http://www.google-analytics.com/collect",
      {
        v: '1',
        tid: 'UA-xxxxxx-1',
        cid: 'a7a364d8-0d14-4e77-b637-xxxxxxxxxx',
        t: 'item',
        ti: '21001',
        in: 'товар2',
        ip: '300.00',
        iv: 'категория2'
      },
      onAjaxSucces
    );

    , либо определить анонимную функцию в аргументах:
    $.post(
      "http://www.google-analytics.com/collect",
      {
        v: '1',
        tid: 'UA-xxxxxx-1',
        cid: 'a7a364d8-0d14-4e77-b637-xxxxxxxxxx',
        t: 'item',
        ti: '21001',
        in: 'товар2',
        ip: '300.00',
        iv: 'категория2'
      },
      function(data) {
        // do something with data
      }
    );

    Второй вариант предпочтительнее, если функция не переиспользуется.

    $.post так же может принимать аргументом объект с параметрами.
    Ответ написан
  • Как перебрать все числа на странице, умножив их на 2?

    rockon404
    @rockon404
    Frontend Developer
    ES5:
    $('.num').text(function(_, num) {
      return num * 2;
    });

    ES6:
    $('.num').text((_, num) => num * 2);
    Ответ написан
    Комментировать
  • Почему render выполняеться перед componentWillMount?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Потому что библиотека не ожидает возвращаемое значение в componentWillMount и следом сразу вызывает render.
    Забудьте этот метод - он не рекомендован к использованию. Как уже писали выше, асинхронные запросы рекомендуется инициировать в componentDidMount. Он выполняется после вызова render, который вы по какой-то неясной причине хотите избежать.

    Вот два варианта решения:
    1. До загрузки данных возвращать в render null или прелоадер.
    render() {
       const { data } = this.props;
    
       if (!data) return null;
         
        return (
          <div>
            <FilterModels />
          </div>
        )
      }
    }

    2. Переместить загрузку данных в родительский компонент и отрисовывать целевой по условию:
    render() {
      const { filterData } = this.props;
      return (
        <Wrapper>
          {filterData  && <FilterForm data={filterData} />}
       </Wrapper>
      )
    }
    Ответ написан
    Комментировать
  • Как правильно организовать общение между компонентами?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Можно сделать так:
    1. Метод оnClick передается из родительского компонента.
    2. state иконки высчитывается по полученным props, но так же меняется по клику, для более комфортного пользовательского опыта.
    3. По возвращению ответа от сервера обновляется вся карточка. Так же, обновляется state иконки в computeDerivedState, мало ли была ошибка и товар не попал в избранное.
    4. В случае ошибки, левом нижнем углу экрана можно показать всплывающее уведомление. Для этого можно написать action и вызывать его в блоке catch асинхронных действий.
    Ответ написан
  • Как сделать глобальную переменную в REACT?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Хорошим вариантом будет передавать переменные зависимые от окружения в webpack.DefinePlugin:
    new webpack.DefinePlugin({
      '__HOST__': JSON.stringify('https://example.com')
    });

    В коде:
    xhr.open("GET", __HOST__ + `/api/v1.0/items/${first}/${this.state.itemPerPage}`, true);
    Ответ написан
    4 комментария
  • Какой использовать тег?

    rockon404
    @rockon404
    Frontend Developer
    white-space: pre-line;

    Демо.

    В обоих случаях, можно еще использовать:
    word-break: break-word;
    Ответ написан
    Комментировать
  • React, как это работает?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Запись:
    state = {
      filteredNews: this.props.data,
    };

    аналогична:
    constructor(props) {
        super(props);
        this.state =  {
          filteredNews: this.props.data,
        };
      }

    this.props.data записывается в state единожды в конструкторе. В последствии, при получении нового значения this.props.data, state не изменяется.

    Нет никакой необходимости определять renderNews как стрелочную функцию, ее следует переделать в метод класса.

    Было:
    renderNews = () => {};
    стало:
    renderNews() {}

    Я бы внес в renderNews следующие изменения, помимо переделывания в метод класса:
    1. ранний return вместо переменной и блока else,
    2. замена обычной функции на стрелочную в колбеке map.

    Результат:
    renderNews() {
      const { filteredNews } = this.state;
    
      if (filteredNews.length) {
        return filteredNews.map(item => (
          <Article key={item.id} data={item} />
        ));
      }
    
      return <p>К сожалению новостей нет</p>;
    }
    Ответ написан
    4 комментария
  • Отличие MVVM от MVP?

    Комментировать
  • Как отправить запрос на выбраный день в календаре?

    rockon404
    @rockon404
    Frontend Developer
    А документацию почитать слабо?
    Ответ написан
    Комментировать
  • Как отрендерить компоненту react только после ajax запроса, который обновит store?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    render() {
      const { someStateKey } = this.props;  
    
      if (!someStateKey) return null;
    
      return (
        {/* component JSX code */}
      );
    }
    Ответ написан
    2 комментария
  • Для создания приложения на React, нужно ли сначала целиком делать верстку приложения?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Нет, это будет двойная работа. В реальном проекте программист:
    1. Описывает компонент
    2. Пишет JSX разметку в render
    3. Стилизует компонент, в зависимости от выбранной технологии
    4. Пишет необходимые методы и слушатели
    Ответ написан
    1 комментарий
  • Как сделать "динамический" padding?

    rockon404
    @rockon404
    Frontend Developer
    Как правильно верстают контейнер для контента:
    .container {
      width: calc(100% - 32px);  // отступ по 16px в случае если страница <= 1024px
      max-width: 1024px;  // размер для примера
      margin: 0 auto;
    }


    max-width можно задать 100% и напрямую задать padding, само собой к ширине + 32px

    .container {
      width: 100%;
      max-width: 1056px;
      margin: 0 auto;
      padding: 0 16px;
    }
    Ответ написан
    2 комментария
  • Существует ли частичная работа у php-программистов?

    rockon404
    @rockon404
    Frontend Developer
    Если вы толковый специалист, можно попробовать устроиться на частичную занятость в одну из компаний, занимающуюся аутсорс-разработкой. Если нет, то вряд ли, так как от вас скорей всего будет больше вреда, чем пользы.
    Лучшим вариантом, по мне, в вашем случае будет фриланс. Тот же upwork.
    Ответ написан
    Комментировать
  • Как создаются электронные кошелки?

    rockon404
    @rockon404
    Frontend Developer
    Для осуществления подобной деятельности на территории РФ, вы должны быть банком или РНКО, иначе надолго присядите.
    Естественно, любая подобная система работает через API.
    Ответ написан
    2 комментария
  • Почему свойства объекта не получает значение других свойств?

    rockon404
    @rockon404
    Frontend Developer
    Через this в литерале объекта(вне тела функции) вы обращаетесь к глобальному контексту - window или undefined в строгом режиме. Демо.
    Можно использовать геттер:
    var lol = {
      salary: 15,
      bonus: 100,
      gen: 'girl',
      get total() {
         return this.salary + this.bonus;
       }
    }
    
    console.log(lol.total);

    или метод:
    var lol = {
      salary: 15,
      bonus: 100,
      gen: 'girl',
      getTotal() {
         return this.salary + this.bonus;
       }
    }
    
    console.log(lol.getTotal());
    Ответ написан
    Комментировать