• Комбинатор "+" в CSS выделяет только 1 последующий элемент, или несколько?

    rockon404
    @rockon404
    Frontend Developer
    a ~ b – правые соседи: все b на том же уровне вложенности, которые идут после a.
    a + b – первый правый сосед: b на том же уровне вложенности, который идёт сразу после a

    В списках удобно задавать отступы между элементами комбинацией a + a:
    .list-item + .list-item {
      margin-top: 10px;
    }

    sass версия:
    .list-item {
    
      & + & {
        margin-top: 10px;
      }
    }

    это правило применит margin-top ко всем элеметнам списка кроме первого. Конечно, при условии что в списке все элементы будут иметь селектор .list-item:
    <ul>
      <li class="list-item"></li>
      <li class="list-item"></li>
      <li class="list-item"></li>
      <li class="list-item"></li>
      <!--        ...         -->
      <li class="list-item"></li>
    </ul>
    Ответ написан
    Комментировать
  • Какую книгу выбрать для изучения программной архитектуры компьютера?

    rockon404
    @rockon404
    Frontend Developer
    Таненбаум Э. "Архитектура компьютера"
    Ответ написан
    Комментировать
  • Почему асинхронный запрос не выполняется?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Поправьте mapStateToProps:
    const mapStateToProps = state => {
      return {
        items: state.items.items,
        error: state.items.error,
        loading: state.items.loading
      };
    };

    По-хорошему напишите селекторы.

    2. Измените кейс FETCH_SUCCESS:
    export function items(state = initialState, action) {
      const { type, payload } = action;
    
      switch (type) {
    
        // some code
    
        case "FETCH_SUCCESS":
          return { 
            ...state,
            items: [ ...state.items, ...payload.items ],
            loading: false,
          };
    
         // some code
    
      }
    }


    3. По возможности сокращенный вариант:
    export const fetchProductsBegin = () => ({ type: FETCH_BEGIN });
    
    const mapStateToProps = state => ({
      items: state.items.items,
      error: state.items.error,
      loading: state.items.loading,
    });


    https://codesandbox.io/s/jprm2omlr5
    Ответ написан
    1 комментарий
  • Как импортировать несколько компонентов с app.js в react?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    app.js
    export Gap;

    index.js
    ReactDOM.render(<Gap /> , document.getElementById('example'));


    А вообще Gap лучше вынести в отдельный файл.
    Ответ написан
    1 комментарий
  • Как нормально перебрать json?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вам бы перед тем как браться такие вещи реализовывать, хорошенько основы JavaScript изучить.
    В первом случае у вас в json массив, во втором объект содержащий массив.
    Перебрать элементы во втором случае можно так:
    {cont.continents.map(el => (
      <li key={el.code}>{el.name}</li>
    ))}


    Я вам настоятельно рекомендую пока отложить React и потратить пару дней на изучение основ JavaScript, а так же синтаксиса ES6, JSX и экспериментальных фич языка используемых в React.
    Ответ написан
    Комментировать
  • Stylelintrc, jshintrc: что означает rc в конце?

    rockon404
    @rockon404
    Frontend Developer
    Configuration files also do more than just modify settings, they often (in the form of an "rc file") run a set of commands upon startup (for example, the "rc file" for a shell might instruct the shell to change directories, run certain programs, delete or create files — many things which do not involve modifying variables in the shell itself and so were not in the shell's dotfiles). This convention is borrowed from "runcom files" on the CTSS operating system.

    This functionality can and has been extended for programs written in interpreted languages such that the configuration file is actually another program rewriting or extending or customizing the original program; Emacs is the most prominent such example.

    The "rc" naming convention of "rc files" was inspired by the "runcom" facility mentioned above and does not stand for "resource configuration", "runtime configuration", or "remote control" as is often wrongly guessed.

    "rc" files are traditionally files which end in the "(.)rc" suffix and which contain data and information that is used as configuration information for the associated program. Typically the name of that program is the first part of the rc file's name, with the "(.)rc" suffix being used to indicate the file's purpose, e.g. ".xinitrc", ".vimrc", ".bashrc", "xsane.rc".

    link
    Ответ написан
  • Как мне сделать переход на другую страницу через Link?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    А зачем вы ссылку в роутер оборачиваете? Исправьте:
    <BrowserRouter>
      <Link to="/registration">Зарегестрироваться</Link>
    </BrowserRouter>

    На:
    <Link to="/registration">Зарегестрироваться</Link>
    Ответ написан
    Комментировать
  • Как сделать печать в верхнем регистре только буквы "a"?

    rockon404
    @rockon404
    Frontend Developer
    Есть более простой путь:
    var div = document.getElementById("div3");
    var input = document.getElementById('value_for_div3');
    
    input.addEventListener('keyup', function(e) {
      div.innerHTML = this.value.replace(/а/g, 'A');
    });


    В данном примере заменяется только "а" из кириллицы.

    Если надо заменять и из кириллицы и из латиницы, то регулярное выражение заменяем на:
    div.innerHTML = this.value.replace(/(a|а)/g, '$1'.toUpperCase());

    Символы на вид одинаковые, но коды у них разные.

    Демо.
    Ответ написан
  • Api запрос из react приложения выполняется только один раз, что делать?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    render() {
      const { res } = this.state;
      const shouldFlimDisplayShown = !!res;
    
      return (
        <div>
          <form onSubmit={this.handleSubmit}>
            <label htmlFor="title">Enter title</label>
            <input id="title" name="title" type="text" />
            <button>Send data!</button>
          </form>
          {shouldFlimDisplayShown && <FilmDisplay filmName={res}/>}
       </div>
      );
    }


    import React from 'react';
    
    class FilmDisplay extends React.Component {
       constructor() {
        super();
    
        this.state = {
          filmData: null
        };
      }
    
      componentDidMount() {
        this.fetchMovie();
      }
    
      componentDidUpdate(prevProps) {
        if (prevProps.filmData !== this.props.filmData) {
          this.fetchMovie();
        }
      }
     
      fetchMovie() {
        const { filmName } = this.props;
        const URL = "http://www.omdbapi.com/?t=" + filmName + "&apikey=6540f2ec&";
    
        fetch(URL).then(res => res.json()).then(json => {
          this.setState({ filmData: json });
        });
      }
    
      render() {
        const { filmData } = this.state;
    
        if (!filmData) return <div>Loading</div>;
      
        return <div>{JSON.stringify(filmData)}</div>;
      }
    }
    
    export default FilmDisplay;
    Ответ написан
    Комментировать
  • Когда в методе render React.JS отрисовываю список, и хочу отобразить только например 'name', выводить id елем. +name, с чем это связано?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вам необходимо перед вызовом map преобразовать OrderedMap в массив. Для этого можно использовать метод toArray:
    return arr.delete(id).toArray().map(item => <li key={item.id}>{item.name}</li>);
    Ответ написан
    1 комментарий
  • Почему код выполняется параллельно?

    rockon404
    @rockon404
    Frontend Developer
    В вашем случае, скорей всего, opacity меняется за тысячные доли секунды и срабатывает remove.
    Демо.
    Все шаги выполнения в консоли. На моей рабочей машине opacity меняется с 1 до 0 за 0.005 секунды. Представьте насколько это мало.
    Код синхронный. Выполняться параллельно он не может.
    Ответ написан
  • Почему вылетает ошибка при использовании if?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Потому что это JSX. Можно исправить так:
    render() {
      const { _sharedData: { auth_user } } =  this.props;
    
      const shouldShowIconMenu = +auth_user === 1;
    
      return (
        <AppBar>
          {shouldShowIconMenu && (
            <IconMenu>
              ...
            </IconMenu>
          )}
        </AppBar>
      );
    }


    JSX это все-таки синтаксический сахар над React.createElement. Вызов if-else, как и for внутри JSX транслировался бы в нерабочий код. Пример:
    JSX:
    <div id={if (condition) { 'msg' }}>Hello World!</div>

    В результате трансляции получаем невалидный код:
    React.createElement("div", { id: if (condition) { 'msg' } }, "Hello World!");
    Ответ написан
    2 комментария
  • Как получить данные из массива json в JavaScript?

    rockon404
    @rockon404
    Frontend Developer
    ES5:
    var wor = 'alesh.3';
    var key = 'last30m';
    
    var record = json.data.rows.find(function(el) {
      return el.wor === wor;
    });
    
    var value = record ? record[key] : null;


    ES6:
    const wor = 'alesh.3';
    const key = 'last30m';
    
    const { data: { rows } } = json;
    
    const record = rows.find(el => el.wor === wor);
    const value = record ? record[key] : null;
    Ответ написан
    2 комментария
  • Как отфильтровать массив по другому массиву?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    state.list.filter(item => item.params.some(i => ["качель","окно"].includes(i)));
    Ответ написан
    Комментировать
  • Почему ошибка при установке prettier?

    rockon404
    @rockon404
    Frontend Developer
    ставьте плагин eslint-plugin-react. Дополнительно если не установлены:
    eslint
    babel-eslint
    eslint-plugin-jsx-a11y
    eslint-plugin-import
    eslint-config-prettier
    eslint-config-airbnb
    eslint-plugin-prettier
    Добавляйте так:
    {
      "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"
        }]
      }
    }


    Правила настройте под себя.

    Если хотите precommit проверку, то поставьте lint-stаged и husky, и добавьте следующие строки в package.json:
    "scripts": {
        // ваши скрипты
        "precommit": "./node_modules/.bin/lint-staged",
      },
      "lint-staged": {
        "**/*.js": [
          "./node_modules/.bin/prettier --write",
          "./node_modules/.bin/eslint --fix",
          "./node_modules/.bin/stylelint './app/**/*.js'", // если используете  css in js
          "git add"
        ]
      },

    Теперь перед каждым вашим коммитом код будет приводиться в порядок на автомате если это возможно. И прерывать коммит ошибкой если нарушены правила.
    Ответ написан
  • Как изменить данные из одной "утки" в другой?

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

    Сделайте селекторы checkIsProductAddedToCartSelector и isProductAddedToCartSelector. Первый пусть возвращает функцию принимающую id товара и возвращающую true если товар найден в store корзины. Второй пусть принимает id товара и возвращает булево значение, если товар найден или не найден в store корзины. Используйте для этого reselect.
    И добавляйте их в mapStateToProps в connect.
    В списке можно вызывать так:
    const ProductsList = ({
      productsList,
      checkIsProductAddedToCart,
    }) => (
      <ul>
        {productsList.map(product => (
          <Product
            addedToCart={checkIsProductAddedToCart(product.id)}
            product={product}
          />
        ))}
      </ul>
    );
    
    const mapStateToProps(state => ({
      productsList: productListSelector(state),
      checkIsProductAddedToCart: checkIsProductAddedToCartSelector(state),
    }));
    
    export default connect(mapStateToProps)(ProductsList);

    В детализации так:
    const mapStateToProps((state, ownProps) => ({
      isAddedToCart: isProductAddedToCartSelector(state, ownProps),
    }));
    
    export default connect(mapStateToProps)(ProductDetails);


    Примерные реализации селекторов:
    import { createSelector } from 'reselect';
    
    const cartSelector = state => state.cart;
    
    const cartProductsSelector = createSelector(
      cartSelector,
      cart => cart.products,
    );
    
    // возвращает функцию, принимающую id, которую можно использовать при построении списков
    const checkIsProductAddedToCartSelector = createSelector(
      cartProductsSelector,
      products => id => products.some(product => product.id === id),
    );
    
    const productIdSelector = (_, props) => props.product.id;
    
    // возвращает булево значение, важно чтобы в компоненте было свойство product
    const isProductAddedToCartSelector = createSelector(
      cartProductsSelector,
      productIdSelector,
      (products, id) => products.some(product => product.id === id),
    );
    Ответ написан
    7 комментариев
  • Живая перезагрузка Hot Module Replacement для нативного JavaScript не работает?

    rockon404
    @rockon404
    Frontend Developer
    Вариант 1. Горячая замена самого модуля:
    const greetings = 'Hello, friend';
    let h1;
    
    function say() {
      h1 = document.createElement('h1');
      h1.innerHTML = greetings;
      document.body.appendChild(h1);
    }
    
    say();
    
    if (module.hot) {
      module.hot.dispose(() => {
        document.body.removeChild(h1);
      });
    
      module.hot.accept();
    }


    Вариант 2. Горячая замена дочернего модуля:
    Добавьте модуль greetings.js:
    const greetings = 'Hello, friend';
    
    export default greetings;

    и измените основной модуль так:
    import './styles.css';
    
    let greetings = require('./greetings').default;
    let h1;
    
    function say() {
      h1 = document.createElement('h1');
      h1.innerHTML = greetings;
      document.body.appendChild(h1);
    }
    
    say();
    
    if (module.hot) {
      module.hot.accept('./greetings', () => {
        greetings = require('./greetings').default;
        document.body.removeChild(h1);
        say();
      });
    }

    Если не используется транспиляция модулей из ES6 в CommonJS, то должно работать и так:
    import './styles.css';
    import greetings from './greetings';
    
    let h1;
    
    function say() {
      h1 = document.createElement('h1');
      h1.innerHTML = greetings;
      document.body.appendChild(h1);
    }
    
    say();
    
    if (module.hot) {
      module.hot.accept('./greetings', () => {
        document.body.removeChild(h1);
        say();
      });
    }
    Ответ написан
    6 комментариев
  • Как добавить изменения ветки master в свою ветку, не потеряв изменения в последней?

    rockon404
    @rockon404
    Frontend Developer
    Опционально делаете fetch:
    git fetch
    Затем выполняете слияние:
    git merge origin/feature-branch-name
    Если есть конфликты резолвите удобным способом и коммитите:
    git commit -a
    Затем отправляете изменения в свою удаленную ветку:
    git push
    Ответ написан
    1 комментарий
  • Как убрать eslint warnings одной командой?

    rockon404
    @rockon404
    Frontend Developer
    Поставьте prettier.
    Добавьте его в .eslintrc:
    {
      "extends": [
        "airbnb",
        "prettier",
      ],
      "plugins": [
        "prettier"
      ],
      "parser": "babel-eslint"
    }


    Исправить код можно командой:
    prettier --write
    Ответ написан
    2 комментария
  • На чем сверстан сайт https://ru.bookmate.com?

    rockon404
    @rockon404
    Frontend Developer
    Написан на React. CSS весь свой.
    Ответ написан
    Комментировать