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

    rockon404
    @rockon404
    Frontend Developer
    Можно так:
    var duration = 32 * 60 * 1000;
    var step = 1000;
    var endsAfter = duration;
    
    var timer = setTimeout(alert, duration, 'Hello world!');
    
    var interval = setInterval(function() {
      endsAfter -= step;
      if (endsAfter <= 0) clearInterval(interval);
      console.log('Timeout через: ', endsAfter);
    }, step);

    Демо
    Ответ написан
    Комментировать
  • Вопрос по документации Reactjs Lists and Keys?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вы наверно не заметили, но массив в примерах называется numbers, а аргумент колбека в который передается элемент массива number.

    Исходные данные:
    const numbers = [1, 2, 3, 4, 5];
    const listItems = numbers.map((number) =>
        <li key={number.toString()}>
          {number}
        </li>
      );


    Результат выполнения метода map, в виде JSX:
    [
      <li key="1">1</li>,
      <li key="2">2</li>,
      <li key="3">3</li>,
      <li key="4">4</li>,
      <li key="5">5</li>,
    ]

    Результат в виде JS:
    5a8201cac8298094680322.png

    После рендера массива:
    <ul>
      {listItems}
    </ul>

    получаем следующий html:
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
    </ul>


    О методе массива map можете почитать тут.
    Ответ написан
    Комментировать
  • Почему props меняется сразу для всех, а не для каждого отдельно, react/redux?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Можно сделать isLoading и хранилище сущностей объектом:
    const initialState: {
      entities: {}.
      isLoading: {
        'ALL': false, 
      },
       isError: {
        'ALL': false, 
      }
    }


    const someEntityReduser = (state = initalState, action) => {
      const { type, payload } = action;
    
      switch (type) {
        case GET_ALL_ENTITIES_REQUEST:
          return {
            ...state,
            isLoading: {
              ...state.isLoading,
              'ALL': true, 
            },
            isError: {
              ...state.isError,
              'ALL': false, 
            },
          };
    
        case GET_ALL_ENTITIES_SUCCESS:
          return {
            ...state,
            entities: payload,  // либо нормализация если приходят массивом
            isLoading: {
              ...state.isLoading,
             'ALL': false,
            },
          };
    
        case UPDATE_ENTITY_REQUEST:
          return {
            ...state,
            isLoading: {
              ...state.isLoading,
              [payload.id]: true, 
            },
            isError: {
              ...state.isError,
              [payload.id]: false, 
            },
          };
          
        case UPDATE_ENTITY_SUCCESS:
          return {
            ...state,
            entities: {
               ...state.entities,
               [payload.id]: payload,  
            },
            isLoading: {
              ...state.isLoading,
              [payload.id]: false,
            },
          };
        
         /* other cases */
      }
    }
    Ответ написан
  • Адекватный ли конструктор?

    rockon404
    @rockon404
    Frontend Developer
    Не понимаю назначения этой сущности, но это не конструктор. Метод viewer назван неправильно, так как название не говорит ничего о том, что этот метод делает.
    Конструкгор это когда так:
    spoiler
    function SetUserManager(config) {
      this.client = new ClientUser();
      this.clientManager = new ClientManager({
        user: this.client
      });
    
      this.options = {
        name: config.name,
        key: config.key
      };
    
      this.cookies = [];
    
      client.login(options);
      this.viewer();
    }
    
    SetUserMagager.prototype.viewer = function() {
      this.client.on('login', () => {
        this.client.setLogin();
      });
    
      this.client.on('msg', (session) => {
        serveSession(session);
      });
    
      this.clientManager.on('user', (data) => {
        serveNewUser(data);
      });
    }

    или так:
    spoiler
    class SetUserMagager {
      constructor(config) {
        this.client = new ClientUser();
        this.clientManager = new ClientManager({
          user: this.client
        });
    
        this.options = {
          name: config.name,
          key: config.key
        };
    
        this.cookies = [];
    
        client.login(options);
        this.viewer();
      }
      
      viewer() {
        this.client.on('login', () => {
          this.client.setLogin();
        });
    
        this.client.on('msg', (session) => {
        	serveSession(session);
        });
    
        this.clientManager.on('user', (data) => {
          serveNewUser(data);
        });
      }
    }

    Складывается впечатление, что вы везде пытаетесь использовать ООП и плодите сущности там, где они не нужны и где лучше использовать функциональный стиль.

    Насчет ваших обработчиков ничего не скажешь так как не ясно, ни что такое ClientUser и ни что такое ClientUserManager.
    Ответ написан
    2 комментария
  • Как вернуть значени из модуля из асинхроной функции?

    rockon404
    @rockon404
    Frontend Developer
    Если вы хотели вернуть результат из person то так:
    module.exports.person = async () => await sqlQuery();

    Другое дело, что async/await тут и не нужны.
    Их использование было бы оправдано сели бы надо было сделать что-то вроде:
    module.exports.person = async () => [await sqlQuery1(), await sqlQuery2()];

    или:
    module.exports.person = async id => {
      const user = await getUser(id);
      const permissions = await getPermissions(user.role);
     
      return {
        user,
        permissions,
      };
    }

    В вашем случае достаточно:
    module.exports.person = args => sqlQuery(args);
    А использовать уже можно в асинхронных функциях:
    const user = async person(id);
    Ответ написан
    Комментировать
  • Как обратиться к аргументам конструктора класса?

    rockon404
    @rockon404
    Frontend Developer
    Обратиться к аргументам конструктора из методов класса нельзя, но можно сделать их в конструкторе полями класса:
    class Counter {
      constructor(value) {
        this.value = value || 0;  // определяем поле класса value со значением аргумента value
      }                           // либо 0 если аргумент не будет передан
      
      getVaue() {
        return this.value;
      }
    
      increment() {
        return ++this.value;
      }
    
      decrement() {
        return --this.value;
      }
    }


    Связанный список рекомендую попробовать написать своими силами. Если не хотите сами, то смотрите под спойлером.
    spoiler
    class Node {
      constructor(data) {
        this.data = data;
        this.next = null;
      }
    }
    
    class LinkedList {
      constructor() {
        this.head = null;
        this.length = 0;
        
        Array.prototype.forEach.call(arguments, data => this.add(data));
      }
    
      add(data) {
        const nodeToAdd = new Node(data);
        let nodeToCheck = this.head;
    
        if(!nodeToCheck) {
          this.head = nodeToAdd;
          this.length++;
          return nodeToAdd;
        }
    
        while(nodeToCheck.next) {
          nodeToCheck = nodeToCheck.next;
        }
        
        nodeToCheck.next = nodeToAdd;
        this.length++;
    
        return nodeToAdd;
      }
    
      get(num) {
        const nodeToCheck = this.head;
        let count = 0;
      
        if(num > this.length) {
          return "Doesn't Exist!"
        }
    
        while(count < num) {
          nodeToCheck = nodeToCheck.next;
          count++;
        }
    
        return nodeToCheck;
      }
    
      remove(num) {
        let nodeToCheck = this.head;
        let length = this.length;
        let count = 0;
        let prevNode = null;
         
         if(num > length) {
           return "Doesn't Exist!"
         }
       
         if(num === 0) {
           this.head = nodeToCheck.next;
           this.length--;
           return this.head;
         }
         
         while(count < num) {
           prevNode = nodeToCheck;
           nodeToCheck = nodeToCheck.next;
           count++;
         }
         
         prevNode.next = nodeToCheck.next;
         nodeToCheck = null;
         this.length--;
          
         return this.head;
      }
    }
    Ответ написан
  • Как при первой загрузке страницы отображать не дефолтный роут?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Если вы имели ввиду первое посещение сайта с конкретного браузера, то для решения этой задачи можно использовать localstorage:
    import React, { Component } from 'react';
    import { Redirect } from 'react-router-dom';
    
    const isVisited = localStorage.getItem("isVisited");
    
    if (!isVisited) {
      localStorage.setItem("isVisited", true);
    }
    
    
    class Home extends Component {
      ...
      render() {
        if (!isVisited) return <Redirect to="/nobel-laureates" />
        ...
      }
    }
    Ответ написан
    Комментировать
  • Как реализовать блок шириной больше .container?

    rockon404
    @rockon404
    Frontend Developer
    Можно так:
    <header>
      <div class="container">
        <!-- Header stuff -->
      </div> 
    </header>
    <main>
      <div class="container">
        <!-- Optional stuff -->
      </div>
      <div class="big-green-block">
        <!-- Big green block stuff -->
      </div>
      <div class="container">
        <!-- Some other stuff -->
      </div>
    <main>
    Ответ написан
    Комментировать
  • Как задать стиль к символам внутри элемента?

    rockon404
    @rockon404
    Frontend Developer
    Можно так.
    Eще вариант с обработкой строки за один проход.
    Ответ написан
    1 комментарий
  • Как проверить скорость выполнения кода?

    rockon404
    @rockon404
    Frontend Developer
    Если интересует конкретный узел, можно использовать performance.now:
    var t0 = performance.now();
    doSomething();
    var t1 = performance.now();
    console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.");

    Для асинхронных задач:
    var t0 = performance.now();
    var t1;
    doSomething().then(result => {
      t1 = performance.now();
      console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.");
    });
    Ответ написан
    1 комментарий
  • Что значит эта строка кода?

    rockon404
    @rockon404
    Frontend Developer
    Опционально добавляется регулярное выражение в query string запроса, доступное по ключу description2__regex.
    Если вопрос только по синтаксису, то испльзуются шаблонные строки.
    Ответ написан
    2 комментария
  • Async await изнутри - как устроено?

    rockon404
    @rockon404
    Frontend Developer
    async/await лишь удобная обертка над промисами. Подробней о async/await можете почитать тут.
    1000 выводится раньше потому, что функция, благодаря использованию ключевого слова await, дожидается ответа от Promise возвращаемого функцией sleep и только после этого продолжает выполнение.
    В V8 async/await так же как и Promise реализованы на JavaScript. С реализацией можно ознакомиться тут.
    Как можно видеть реализована она на генераторах.

    Аналог вашего примера без использования async/await:
    const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
    
    (() => {
        setTimeout(() => console.log('1000'), 1000);
        sleep(5000).then(() => {
          console.log('5');
        });
    })();

    Так же async function всегда возвращает Promise, даже если вы ничего не возвращаете.
    Ответ написан
    2 комментария
  • Можно ли менять state внешнего компонента через props?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Если попытаетесь изменить this.props, получите исключение:
    Cannot assign to read only property
    2. У вас есть возможность мутировать state, вот только делать это не нужно.

    Хороший способ управления состоянием компонентов через родителя:
    class Example extends Component {
      state = {
        inputValue: '',
      };
    
      handleChange = e => { 
        const { name, value } = e.target;
        
        this.setState({
          [name]: value,
        });
      };
    
      render() {
        const { inputValue } = this.state;
    
        return (
          <Wrapper>
            <input
              name="inputValue"
              value={inputValue}
              onChange={this.handleChange}
            />
            ...
          </Wrapper>
        );
      }
    Ответ написан
    7 комментариев
  • Почему не работает массив javascript?

    rockon404
    @rockon404
    Frontend Developer
    Передавайте имена файлов строками:
    var variants = {
      '66': {'images_names':['4984534-1_1.jpg', '4984534-2_1.jpg'], 'v_id':[66]},
      '208': {'images_names':['4984534-3_1.jpg', '4984534-4_1.jpg'], 'v_id':[208]},
     };
    Ответ написан
    1 комментарий
  • Почему use strict не работает в setTimeout?

    rockon404
    @rockon404
    Frontend Developer
    Потому что setTimeout вызывает колбек в контексте window.
    Что-то вроде:
    func.apply(window);

    Стоит добавить, что при выполнении скрипта воркером this в колбеке setTimeout будет ссылаться на WorkerGlobalScope.
    Ответ написан
    6 комментариев
  • Как получить nextState, приходит в this.state прошлое значение state?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    setState асинхронная функция и в нее можно передать колбек вторым аргументом:
    this.setState({ ... }, () => this.getStateValues());


    По-хорошему вам следует переписать хандлер, так как вы создаете новые копии каждый рендер, тем более вы передаете свойство name в инпуты, но почему-то не используете в хандлере.
    Перепишите так:
    handleChange = ev => {
       const { name, value } = ev.target;
       const symbols = split('')(value);
       const result = filter(i => characterVerification(i), symbols);
    
       this.setState({
         [name]: join('')(result)
        }, () => this.getStateValues(),
      );
    };


    Еще непонятно зачем было тянуть в проект ramda.
    Ответ написан
  • Странное поведение React. Состояние дочерних элементов то само прокидывается, то нет. Почему?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вам бы основы JavaScript подтянуть.
    Во-первых вы биндите контекст хандлера на AppField в конструкторе:
    constructor(props) {
      super(props);
      this.state = props.params;
      this.onFieldChange = this.onFieldChange.bind(this); // тут
    }

    Во-вторых, вы определяте переменную self, ссылающуюся на this и она ни делает ровным счетом ничего, так как вы передаете функцию в колбек обработчика события:
    renderSingleValue(data = {}) {
      ...
      let self = this;  // бессмысленно
    
      return (
        <input type="text"
          ...
          onChange={self.onFieldChange} 
          ...
        />
      );
    }

    Даже если бы функция не была забинжена на AppField, у вас бы все-равно ничего не получилось.

    В-третих, значение инпутов лучше хранить в родителе, а не в самих инпутах.

    Трюк с self работает в отложенных вызовах:
    constructor() {
      const self = this;
    
      node.addEventListener('click', function() {
        self.handleEvent();  // сработает, так как функция вызывается на self
      });
    }

    и не сработает при передаче функции:
    constructor() {
      const self = this;
    
      node.addEventListener('click', self.handleEvent);  // не сработает, функция передается
                                                         // в колбек обработчика события
    }                                                    // и не будет вызываться на self


    Пример как можно сделать контролируемую форму с состоянием инпутов в родителе:
    class Example extends Component {
      state = {
        inputValue: '',
      };
    
      handleChange = e => {  // arrow class field function биндится на контекст экземпляра
        const { name, value } = e.target;
        
        this.setState({
          [name]: value,
        });
      };
    
      render() {
        const { inputValue } = this.state;
    
        return (
          <Wrapper>
            <input
              name="inputValue"
              value={inputValue}
              onChange={this.handleChange}
            />
            ...
          </Wrapper>
        );
      }
    }

    Аналогичное решение без использования class field function:
    class Example extends Component {
      constructor(props) {
        super(props);
        this.state = {
          inputValue: '',
        };
        this.handleChange = this.handleChange.bind(this);
      }
      
    
      handleChange(e) {
        const { name, value } = e.target;
        
        this.setState({
          [name]: value,
        });
      }
    
      render() {
        const { inputValue } = this.state;
    
        return (
          <Wrapper>
            <input
              name="inputValue"
              value={inputValue}
              onChange={this.handleChange}
            />
            ...
          </Wrapper>
        );
      }
    }


    Если делаете совой компонент вроде кастомного select, то вы можете в его реализации по изменению сами вызывать хандлер onChange, передавая туда фейковое событие с нужными вам ключами:
    handleChange = value => {
      const { name, onChange } = this.props;
      const fakeEvent = { target: { name, value } };
    
      onChange(fakeEvent);
    };
    Ответ написан
    Комментировать
  • Зачем в React так записывают в state?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Во-первых в setState в корень предыдущее состояние передавать не нужно, так под капотом к нему так и так подмешается предыдущее состояние, в не зависимости от того, что вы туда передадите. Примерно так:
    state = { ...prevState, ...newState };

    Во-вторых не правильно передавать в setState this.state, так как setState выполняется асинхронно и ваше текущее состояние может успеть измениться. Если надо обновить состояние на основе предыдущего, в setState по-хорошему надо передавать функцию, в которую первым аргументом при вызове придет ваше состояние:
    this.setState(prevState => ({
      some_data: {
        ...prevState.some_data,
        ...input,
      },
    });
    Ответ написан
    3 комментария