Задать вопрос
  • Что такое {Component}? И для чего оно в конкретном примере?

    miraage
    @miraage
    Старый прогер
    Это называется named export. Изюминка в том, что у React есть только default export.
    Вопрос - как оно тогда работает, если это named export, а у React только default?

    Ответ в том, что React поставляется как CommonJS версия, а не ESModule.
    Можно увидеть в исходниках, что везде в конце пишется "module.exports = React"
    https://unpkg.com/react@16.8.6/index.js
    https://unpkg.com/react@16.8.6/cjs/react.development.js
    https://unpkg.com/react@16.8.6/cjs/react.productio...

    Дальше происходит магия (вероятно, вебпака), и получается, что default export дополнительно продублирован named export'ами.

    Смотрите пример: https://codesandbox.io/embed/charming-wilbur-b6fwo

    Я везде пишу React и всем советую.
    И по поводу "меньше символов":

    // 70 chars
    import React from 'react';
    export class Foo extends React.Component {};
    
    // 79 chars
    import React, { Component } from 'react';
    export class Foo extends Component {};
    Ответ написан
    Комментировать
  • Есть ли бесплатный сервер для скрипта Node.Js?

    @slava-belaev
    Firebase Hosting от Google.
    https://firebase.google.com/docs/hosting
    Ответ написан
    Комментировать
  • Как разбить большой файл в node.js на несколько поменьше?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Этот вопрос более общий, чем Ваш случай с node.js и даже более общий, чем JavaScript вообще. Хорошо разделить свой код на части, выделить абстракции, дать им названия и объединить их в одно целое - это одна из главных задач программиста на любом языке.

    Я сначала отвечу на частный вопрос по Node.js и JavaScript, а потом объясню эту тему глубже. Для Node.js есть require, при помощи которого можно импортировать из других модулей. Это реализация Dependency Lookup, т.е. мы имеем несколько модулей и каждый из них знает, от каких он зависит и может запросить менеджер зависимостей дать ссылку на то, что экспортирует другой модуль (в данном случае файл). Например, мы можем сделать require('./matrix.js') или require('./lib/matrix.js') и таким образом получим ссылку на то, что экспортирует matrix.js через module.exports = { ... };. Пример кода с импортом: names.js

    В этот самый module.exports мы отдаем ссылку на функцию ил на объект или массив, который содержит все, что мы хотим экспортировать (можно экспортировать и скалярное значение, но это практически не нужно). В подавляющем большинстве случаев экспортируют объект (используя его как справочник экспортируемых идентификаторов), чуть реже одну функцию (иногда фабрику или функцию обертку) или конструктор прототипа (или класса). Пример кода с экспортом: lib/submodule2.js

    Но можно импортировать зависимости целыми массивами, например тут: main.js Если посмотреть чуть шире ноды, на JavaScript, то есть способ импорта/экспорта через ключевые слова import и export. Примеры: import.mjs и export.mjs

    Документацию модно почитать тут:
    1. Модули для Node.js через require/module.exports: https://nodejs.org/api/modules.html
    2. Модули для Node.js через import/export: https://nodejs.org/api/esm.html
    3. Модули для JavaScript через import/export: https://developer.mozilla.org/en-US/docs/Web/JavaS... и https://developer.mozilla.org/en-US/docs/Web/JavaS...

    Но это все техническая реализация, гораздо важнее то, как мы разбиваем наш код на модули или абстракции. Тут нужно ввести понятие связывание и классифицировать методы связывания (частей кода):
    1. Через общие данные (самое жесткое связывание)
    2. Через вызовы (обычно между модулями с экспортом и импортом)
    3. Через события (самое легкое, между слабосвязанными программными компонентами)

    Если из разных функций, прототипов и классов (их методов) Вы обращаетесь к одним и тем же данным, а тем более, меняете их, то это очень плохо. Могут быть общие идентификаторы такие, но это только константы, которые не меняются из разных мест. Могут быть группы функций, которые должны видеть одну переменную и менять ее, но их нужно объединять друг с другом через замыкания и частичное применение. И такие, связанные через данные конструкции (сильно связанные) должны находиться только внутри одного файла. Изменение одних и тех же данных из разных мест, может привести к формированию сложного и непредсказуемого состояния, а в конечном итоге к ситуациям, когда комбинаторный взрыв состояния не может быть адекватно обработан программой, все случаи просто не покрыты условиями и мы даже не можем себе представить и учесть в коде все случаи.

    Вызовы - это гораздо более безопасный способ взаимодействия программных компонентов, поэтому мы используем его для интерфейса между модулями и между классами и прототипами. Мы экспортируем/импортируем коллекции функций (API) или коллекции классов, что предполагает, что все взаимодействие между ними будет через вызовы (даже обращение к свойствам может быть перехвачено геттерами и сеттерами). Об этом способе связывания модулей я уже выше много сказал.

    Наименее жесткий способ связывания - через события. Тут один программный компонент (модуль, класс, прототип, функтор) может подписаться на события другого или вызывать события у себя или в другого не ожидая, что там есть подписчики. Конечно тут могут быть проблемы с контрактами событий, т.е. именами и форматами данных, они все указаны не жестко и тут может быть много ошибок. Это очень гибкий способ, но он таит в себе потенциальные проблемы совместимости. Так что, где можно обойтись вызовами, то лучше не использовать события.

    Есть еще один средний способ между вызовами и событиями, это callback (и listener). При помощи него события и сделаны, практически, в метод .on(name, callback) (или его аналоги) передается функция callback в качестве аргумента. На этом способе построено асинхронное программирование, в том числе такие способы связывания, как асинхронная последовательная композиция и асинхронная параллельная композиция функций, чеининг и промисы.
    Ответ написан
    1 комментарий
  • Решать задачи VS Продолжать учиться?

    KickeRocK
    @KickeRocK
    FrontFinish
    Ничего не учите и не делайте.
    Всё, ответственность снята, спите спокойно.
    Потом скажете, что могли стать крутым прАграммистом, но Андрей с тостера помешал.
    Загуглите "карта развития фронта" и попробуйте найти работу трейни, лучше по знакомству
    Ответ написан
    Комментировать
  • Как вызвать функцию из ...spread?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Вопрос абсолютно непонятен, но попробую поугадывать:
    const f = (...callbacks) => {
      // spread собирает аргументы в массив,
      // поэтому и работать с ними можно как с массивом
      callbacks.forEach((callback) => callback());
    }
    
    f(
      () => console.log(1),
      () => console.log(2),
      () => console.log(42),
    );
    Ответ написан
    2 комментария
  • Как правильно отлавливать ошибки в react 16.x?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Оборачивайте дочерний компонент, в котором может возникнуть ошибка, в ErrorBoundary. Никакого особого механизма всплытия ошибок нет.
    Ответ написан
    4 комментария
  • Как собирать проект на фронтенде, если нет бекенда?

    ulkoart
    @ulkoart
    firebase
    mockapi

    Можно сразу юзать crud
    Ответ написан
    Комментировать
  • Как сделать динамический вывод данных при вводе данных в input?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Можно написать простой хелпер withLatest вроде этого:

    export const withLatest = request => {
      let last = 0;
    
      return (...args) =>
        new Promise((resolve, reject) => {
          const current = ++last;
          request(...args)
            .then(res => resolve({ isLatest: current === last, res }))
            .catch(err => reject({ isLatest: current === last, err }));
        });
    };

    async/await вариант
    export const withLatest = request => {
      let last = 0;
    
      return async (...params) => {
        const current = ++last;
        try {
          const res = await request(...params);
          return { isLatest: current === last, res };
        } catch (err) {
          throw { isLatest: current === last, err };
        }
      };
    };



    Использование:
    import Api from '../api';
    import { withLatest } from '../utils';
    
    const withLatestFetchData = withLatest(Api.fetchData);
    
    export const fetchData = query => async (dispatch, state) => {
      dispatch({ type: "LOADING_DATA" });
      try {
        const { isLatest, res } = await withLatestFetchData(query);
        if (isLatest) {
          dispatch({ type: "DATA_SUCCESS", payload: res });
        }
      } catch ({ isLatest, err }) {
        if (isLatest) {
          console.log(err);
        }
      }
    };


    Демо.
    В демо так же добавил debounce и небольшую вероятность завершения фейкового запроса ошибкой.
    Ответ написан
    Комментировать
  • Как вызвать put внутри Promise.then в redux-saga?

    rockon404
    @rockon404 Куратор тега Redux
    Frontend Developer
    function* runPromise() {
      try {
        const result = yield call(promise);
        yield put({
           type: CHANGES_CHANGE_SUCCESS,
           payload: result,
        });
      } catch (error) {
        notify("Ошибка: ", error);
      }
    }
    Ответ написан
    Комментировать
  • Почему не перерисовывается компонент App при изменении его состояния?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Во первых вы мутируете состояния обоих компоненов:
    this.setState(prevState => {
      prevState.fruitList.push("Мандаринка");
      return {
        fruitList: prevState.fruitList
      };
    });

    Что противоречит идеологии react.
    Во-вторых пишите props в state в FruitsList только в конструкторе.
    Ну и передаете несуществующий обработчик в onClick.

    Исправленный вариант.
    Изучайте, делайте выводы.
    Ответ написан
    8 комментариев
  • Вывести элемент по клику, react?

    SvyatYa
    @SvyatYa
    FrontEnd developer
    Да, это называется порталы, вот раздел в документации:
    https://reactjs.org/docs/portals.html
    Ответ написан
    1 комментарий
  • Как лучше всего изучать webpack 4?

    kuzvac
    @kuzvac
    Попробуйте официальную академию вебпака :) https://webpack.academy/
    Ответ написан
    Комментировать
  • Как будет выглядеть аналогичный код на любом action creator?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вопрос поставлен некорректно. Action creators - это функции возвращающие объекты действия(Actions) те, что у вас в actions.js
    Action это объект со свойством type(типом действия) и опционально полезной нагрузкой, который передается в dispatch.

    redux-actions и redux-act это бойлерплейт утилиты для генерации action creators и редьюсеров. Советую пока даже не смотреть в их сторону(а можно и вообще не смотреть), лучше хорошо изучите голый API Redux.
    Еще советую потратить время на знакомство с immutable.js

    И еще, ваш код в actions.js не будет работать, так как функции loading, success, error используются раньше, чем определены.
    Либо поменяйте местами, так чтобы send был объявлен под ними:
    const loading = () => ({ ... });
    const success = () => ({ ... });
    const error = (message) => ({ ... });
    
    export const send = ({ name, phone }) => { ... };

    либо используйте для них ключевое слово function:
    export const send = ({ name, phone }) => { ... };
    
    function loading() { 
      return { ... };
    };
    
    function success() { 
      return { ... };
    };
    
    function error(message) { 
      return { ... };
    };

    А тут можете почитать о разнице между Function Declaration и Function Expression.
    Ответ написан
    Комментировать
  • Нужно ли знать DOM для react?

    @Interface
    Надо понимать что react-DOM базируется на том же обычном браузерном DOM. Реакт предоставляет абстракцию к нему, но все же в конечном итоге вы будете работать с самым обычным DOM'ом. И его знание (как минимум) позволит вам понять принципиальные ограничения платформы. Что можно делать, чего нельзя и т.д. На мой взгляд, стоит уметь хоть немного работать с реальным DOM.

    Плюс есть нюанс: реакт создавался, чтобы решить какую-то проблему. Если вы с ней не столкнетесь, вам вероятно, будет сложнее понять причины существования реакта.
    Ответ написан
    5 комментариев
  • Почему возникает Actions must be plain objects без ReduxThunk?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Потому что redux-thunk это middleware и если бы вы заглянули в его исходники(всего 14 строк), то вы бы увидели, что он перехватывает и вызывает функции, передавая в них нужные аргументы и возвращает результат, не предавая его дальше. Без него их перехватывать нечему и они попадают туда куда не должны попадать и провоцируют ошибку, так как Redux без мiddleware на вход в dispatch принимает только объекты, о чем и говорится в тексте ошибки, которую вы получаете.

    Возвращаемое значение(return) в асинхронных действиях используется только вами, его возвращает вызов dispatch. В редьюсеры, как было озвучено выше, оно не попадает.
    Так как возвращается Promise, его можно использовать как-то так:
    Ваш Async action:
    export const asyncAction = (...someArgs) => async dispatch => {
      const res = await someAsyncCall(...someArgs);
      dispatch({ type: SOME_ACTION_TYPE, payload: res });
    
      return res;
    };

    Использование в коде(явный пример с dispatch):
    componentDidMount() {
      const { dispatch } = this.props;
    
      dispatch(asyncAction(...optionalArgs)).then(result => doSomething(result));
    }

    То же самое с проброской async action через connect:
    componentDidMount() {
      const { asyncAction } = this.props;
    
      asyncAction(...optionalArgs).then(result => doSomething(result));
    }


    Вообще, для использования then значение из асинхронной функции возвращать совсем не обязательно и такой код тоже будет прекрасно работать:
    export const asyncAction = (...someArgs) => async dispatch => {
      const res = await someAsyncCall(...someArgs);
      dispatch({ type: SOME_ACTION_TYPE, payload: res });
    };

    Использование в коде(явный пример с dispatch):
    componentDidMount() {
      const { dispatch } = this.props;
    
      dispatch(asyncAction(...optionalArgs)).then(() => doSomething());
    }
    Ответ написан
    8 комментариев
  • Как правильно спроектировать компонент поиска данных, через store?

    Zatmil
    @Zatmil
    Fullstack-разработчик
    Я подозреваю, что у вас store создаётся вне конструктора компонента, поэтому он общий на библиотеку, но не на экземпляр компонента, ведь store создаётся, когда вы делаете импорт.

    1. Создавать уникальный UID для каждого экземпляра компонента. И уже редьюсерами писать в state[uid]

    2. Реализовать оберточный класс компонента и уже внутри него создавать store и провайдить его.
    Ответ написан
    4 комментария
  • Что означает код "class Root extends Component"?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега React
    Ответ написан
    Комментировать