Ответы пользователя по тегу React
  • Как сверстать полупрозрачный блок на элементе при загрузке?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Ответ написан
    Комментировать
  • React. Обязательно ли использовать constructor(){...} чтобы задать state на основе props?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    class properties экспериментальный синтаксис.
    В этом случае поле state задается после (простой пример) вызова конструктора React.Component, в котором инициализируются преданные props. Поэтому когда вы определяете state, props уже определены и доступны.
    Если используете transform-class-properties, он входит в stage-0, stage-1, stage-2, то смело используйте.
    Ответ написан
    1 комментарий
  • Как интегрировать две технологии: VK API и React.js?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Ошибка проверки ESLint. В react-scripts перед билдом запускается проверка ESLint с правилом no-undef.
    Исправить можно так:
    const VK = window.VK;
    или:
    /*eslint-disable */
    VK.Api.call({
     /* ... */
    });
    /*eslint-enable */

    Using Global Variables with create-react-app
    Ответ написан
    Комментировать
  • Как работать с prettier?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    .eslintrc
    {
      "extends": [
        "airbnb",
        "prettier",
        "prettier/react"
      ],
      "plugins": [
        "prettier"
      ],
      "parser": "babel-eslint",
      "parserOptions": {
        "ecmaFeatures": {
          "jsx": true
        }
      },
      "env": {
        "browser": true,
        "node": true
      },
      "rules": {
        "no-plusplus": 0,
        "no-confusing-arrow": 0,
        "no-restricted-syntax": 0,
        "guard-for-in": 0,
        "class-methods-use-this": 0,
        "jsx-a11y/no-static-element-interactions": 0,
        "jsx-a11y/anchor-is-valid": 0,
        "react/no-danger": 0,
        "react/prop-types": 0,
        "react/jsx-filename-extension": 0,
        "react/jsx-curly-brace-presence": ["error", { "props": "never", "children": "never" }],
        "import/no-unresolved": ["error", { "commonjs": true }],
        "import/extensions": 0,
        "import/no-extraneous-dependencies": ["error", {"devDependencies": true}],
        "import/prefer-default-export": 0,
        "prettier/prettier": ["error", {
          "singleQuote": true,
          "trailingComma": "all"
        }]
      },
      "settings" : {
        "import/resolver": {
          "webpack": {
            "config": "webpack/base.config.js"
          }
        }
      }
    }

    пакеты:
    {
        "assets-webpack-plugin": "^3.5.1",
        "babel-eslint": "^8.2.1",
        "eslint": "^4.18.0",
        "eslint-config-airbnb": "^16.1.0",
        "eslint-config-prettier": "^2.9.0",
        "eslint-import-resolver-webpack": "^0.8.4",
        "eslint-plugin-import": "^2.8.0",
        "eslint-plugin-jsx-a11y": "^6.0.3",
        "eslint-plugin-prettier": "^2.6.0",
        "eslint-plugin-react": "^7.6.1",
        "prettier": "^1.10.2",
    }


    Резолвер нужен если алиасы используете для путей в коде.
    Ответ написан
    2 комментария
  • Return: React Component: будет ли утечка памяти?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Бесполезный велосипед изобретаете.

    Вариант 1. Если используете redux-thunk:
    export const handleError = error => ({ type: 'NEW_ERROR', payload: error });
    export const doSomething = data => ({ type: 'DO_SOMETHING', payload: data });

    import { apiCall } from './api';
    import { handleError, doSomething } from './actionCreators';
    
    export const asyncAction = () => dispatch => {
      try {
        const result = await apiCall();
        dispatch(doSomething(result));
        
        return result;
      } catch (e) {
        dispatch(hanldeError(e));
      }
    };

    аналогичным образом можно использовать блок catch если используете redux-saga.
    Если еще не используете, одно из этих middleware, то рекомендую скорей познакомиться с ними и начать использовать.

    Вариант 2. Если не используете:
    export const handleError = error => ({ type: 'NEW_ERROR', payload: error });
    export const doSomething = data => ({ type: 'DO_SOMETHING', payload: data });

    import { connect } from 'react-redux';
    import { apiCall } from './api';
    import { handleError, doSomething } from './actionCreators';
    
    class ExampleComponent extends React.Component {
      componentDidMount() {
        const { dispatch } = this.props;
    
        apiCall().then(
          res => dispatch(doSomething(res)),
          err => dispatch(handleError(err)),
        );
      }
      
      render() { /* ... */ }
    }
    
    export default connect()(ExampleComponent);

    или:
    import { connect } from 'react-redux';
    import { apiCall } from './api';
    import { handleError, doSomething } from './actionCreators';
    
    class ExampleComponent extends React.Component {
      componentDidMount() {
        const { doSomething, handleError } = this.props;
    
        apiCall().then(
          res => doSomething(res),
          err => handleError(err),
        );
      }
      
      render() { /* ... */ }
    }
    
    mapDispatchToProps = {
      handleError,
      doSomething,
    };
    
    export default connect(null, mapDispatchToProps)(ExampleComponent);


    Вообще, самый простой способ сделать dispatch в store это:
    store.dispatch(someAction());

    Прежде чем начнете изобретать очередной велосипед, настоятельно рекомендую хорошо изучить документацию react, redux и react-redux.
    Ответ написан
    1 комментарий
  • Application error после деплоя на Хероку, в чем проблема?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Что происходит с devDependencies после билда.
    У вас сервер запускается в development режиме, heroku сносит все devDependencies после билда.
    Собственно, причина ошибки шаг за шагом:
    1. Инициализация middleware
    2. Подключение конфига webpack
    3. Подключение выпиленного glob
    4. Error: Cannot find module 'glob'

    Как исправить:
    1. Переписать скрипт start на:
    cross-env NODE_ENV=production node server
    2. Остальное читайте тут
    Ответ написан
    3 комментария
  • Почему не работает Link в react-router?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Потому-что вы используете два роутера в приложении. Из одного хотите поменять контент в другом. Это так не работает.
    Демо.
    Попробуйте открыть старницу Test по нижней ссылке, у вас ничего не получится, так как Router не обрабатывает такой путь, при этом Link успешно подменяет location.
    В верхнем роутере этот путь обрабатывается и контент успешно обновляется.

    Вам надо объединить все в один роутер.
    Демо 2
    Ответ написан
    3 комментария
  • ReactJS + PHP + Axios - как решить проблему Access-Control-Allow-Origin?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Почитайте любую свежую статью по REST API на PHP Так API никто не пишет:
    .get('http://example.com/wp-content/themes/armed/mobile/react.php')

    Для решения проблемы с cors, поставьте nginx и добавьте в hosts хост для вашего проекта, и напишите конфиг для nginx, по которому он будет по разным путям вашего хоста перенаправлять запросы на разные порты.
    hosts:
    127.0.0.1 project
    nginx.conf:
    server {
      listen 80;
      server_name project;
    
      location ^~ / {
        proxy_pass http://localhost:3000/;
      }
      location ^~ /api/ {
        proxy_pass http://localhost:3001/api/;
      }
    }
    Ответ написан
    Комментировать
  • Как работать с данными из query?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Утилита, которой вы парсите query string, возвращает значения в виде строк. Что очевидно.
    Вопрос в чем, собственно? Не знаете как string к number привести?
    Можно так:
    const string = '1';
    const number = Number.parseInt(string);
    Ответ написан
    6 комментариев
  • Где лучше хранить данные?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Забудьте о таких подходах в React. Лишняя бесполезная сущность. Лучше вынести в отдельный модуль сами запросы к API.
    2. Если используете голый API React, то это самый верный путь, так как при изменении state произойдет обновление компонента и его потомков.

    import React, { Component } from 'react';
    import { Child } from './Child';
    import { getSomeData } from './api';
    
    class Parent extends Component {
      state = {
        data: [],
      };
    
      componentDidMount() {
        getSomeData.then(data => this.setState({ data });
      }
    
      render() {
        return <Child data={this.state.data} />;
      }
    }
    Ответ написан
    8 комментариев
  • Как вы строите структуру папок для проекта?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Тыц
    Более подробную информацию о том, что прочитали по ссылке уже ищите в Google. Подробно изучите подходы: feature-first, ducks pattern и почитайте о недостатках подхода file-type-first
    Ответ написан
    2 комментария
  • Как импортировать js библиотеку?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    А зачем в модульном коде манкипатчить window?
    Импортируйте библиотеку в тот файл(модуль) в котором используете.
    import libraryName from 'libraryName';
    
    libraryName.someMethod();

    или:
    import { someMethod } from 'libraryName';
    
    someMethod();


    Почитайте документацию к библиотеке, там все есть.
    Ответ написан
    Комментировать
  • Можно ли добавить несколько обработчиков событий в react?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Example extends Component {
      handleClick = e => {
        const { firstHandler, secondHandler } = this.props;
    
        firstHandler(e);
        secondHander(e);
      };
    
      render() {
        return <button onClick={this.handleClick}>Click me</button>;
      }
    }
    Ответ написан
    5 комментариев
  • Как разделить скрипт на части в React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Ответ написан
    Комментировать
  • Как организовать передача состояния из react в svg?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Лучше создавать спрайт и добавлять его в документ, а иконки забирать по id.
    Компонент на примере Styled Components:
    import React from 'react';
    import styled from 'styled-components';
    
    const SVG = styled.svg`
      display: inline-block;
      vertical-align: middle;
    `;
    
    const Icon = ({ name, ...props }) {
      if (!name) {
        throw new Error('Unknown icon name!');
      }
      return (
        <SVG {...props}>
          <use xlinkHref={`#icon-${name}`} />
        </SVG>
      );
    }
    
    export default Icon;


    Cтилизованая иконка c разными состояниями:
    import React from 'react';
    import styled from 'styled-components';
    import { Icon } from './components';
    
    const StyledIcon = styled(Icon)`
      fill: ${props => props.state.fill};
    `;
    
    const Example = ({ iconState }) => <StyledSVG name="profile" state={iconState} />;
    
    export default Example;


    Styled Components, тут лишь для примера. Подобные компоненты легко реализуются и без использования этой библиотеки.
    Ответ написан
    2 комментария
  • Как перейти по ссылке внутри обработчика событий в react?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    import React, { Component } from 'react';
    import { withRouter } from 'react-router-dom';
    
    class Example extends Component {
      handler = () => {
        this.props.history.push('/cources');
      };
      
      render() { /* ... */ }
    }
    
    export default withRouter(Example);


    Возможно, вам подойдет простой вариант с компонентом Link:
    import React, { Component } from 'react';
    import { Link } from 'react-router-dom';
    
    class Example extends Component {
      render() {
        return <Link to="/cources" />;
      }
    }
    
    export default Example;
    Ответ написан
    Комментировать
  • Полезно ли изучать React/Redux, если хочешь работать с VueJS?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Изучайте то, что больше нравится.
    Хорошо знать и практиковать оба фреймворка(да, да, да: вообще-то React библиотека бла, бла, бла) нет особого смысла.
    Хотите попробовать React - пробуйте.

    ИМХО хорошо изучите React, на Vue переходить не захотите.
    Ответ написан
    3 комментария
  • Как осуществить условный рендеринг в реакте?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    const rows = slides.reduce((acc, el, i) => {
      if(i % 3 === 0) acc.push([]);
      acc[acc.length-1].push(el);
    
      return acc;
    }, []);
    
    return (
      <Wrapper>
        {rows.map((row, index) => (
          <Row key={index}>
            {row.map((slide, i) => <Slide key={i} data={slide} />)}
          </Row>
        ))}
      </Wrapper>
    );
    Ответ написан
  • Почему возникает 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 комментариев
  • Как будет выглядеть аналогичный код на любом 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.
    Ответ написан
    Комментировать