• Как сделать searchable select без react-select?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    input + любым способом сверстанный список результатов.
    Интерфейс компонента можно сделать чтобы он по onChange(выбору опции) передавал в хандлер фейковый синтетический event.
    Ответ написан
    Комментировать
  • Делают ли так в React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Так тоже лучше не делать. Такая конструкция и читается хуже и в нее трудней вносить изменения. Хандлеры лучше передавать явно.

    Давайте лучше разберем более приближенный к реальности кейс:
    const Comment = ({ comment, meta, author, postLike, me }) => {
      const [shouldShowReply, setReply] = useState(false);
    
      const toggleReply = useCallback(() => {
        setReply(s => !s);
      }, []);
    
      const handleLikeClick = useCallback(() => {
        postLike(comment.id, me.id);
      }, []);
    
      const isLiked = useMemo(
        () => meta.likes.some(like => like.user_id === me.id),
        [meta.likes],
      );  
    
      return (
        <Wrapper>
          <Avatar src={user.avatar} to={`/users/${user.slug}`} />
          <CommentBody text={comment.body} />
          <Icon name="like" isActive={isLiked} onClick={handleLikeClick} />
          <Button type="link" onClick={toggleReply}>Reply</Button>
          {shouldShowReply && <ReplyForm />}
        <Wrapper/>
      );
    }
    
    const mapStateToProps = (state, ownProps) => ({
      me: meSelector(state),
      author: commentAuthorSelector(state, ownProps),
      meta: commentMetaSelector(state, ownProps),
    });
    
    const mapDispatchToProps = {
      postLike,
    };
    
    export default connect(mapStateToProps, mapDispatchToProps)(Comment);


    Смотрите, что у нас получается, наш комментарий обрабатывает клик по аватару и клики по кнопкам Like и Reply.
    Клик по аватару обрабатывается ссылкой роутера, а благодаря композиции реализация от нас скрыта и мы просто знаем, что в аватар достаточно передать src картинки и ссылку.
    Клик по лайку обрабатывается асинхронной функцией действием, которая подключается с помощью HOC connect.
    Клик по Reply обрабатывается внутренним хандлером компонента и изменяет его состояние.
    На выходе мы имеем интерфейс для комментария подключенного к хранилищу следующего вида:
    <Comment comment={comment} />
    Для не подключенного:
    <Comment
      me={me}
      author={author}
      meta={commentMeta}
      postLike={postLike}
      comment={comment}
    />

    Плоская структура позволяет нам во-первых быстрей анализировать код.
    Во-вторых без лишних телодвижений его изменять, декомпозировать, подключать к state management библиотеке и тд.

    Геттеры и сеттеры без необходимости лучше никогда не использовать. Так как они, опять же, затрудняют анализ. Исключение - использование инструментов приветствующих их использование.

    И еще - что лучше тут - бинд или стрелочная функция?

    Это есть в документации.
    Ответ написан
    Комментировать
  • Делают ли так в Reacte?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Ненормально так делать. Одна из целей которую преследовали разработчики современных фреймворков это уход от необходимости вручную сверяться с DOM селекторами.
    Подобные места, источник возникновения целого класса багов, когда вы забудете, что селектор используется в JS и переименуете или удалите его. А выяснят, что что-то отвалилось, возможно, только ваши пользователи.
    Можно, конечно, использовать дополнительные селекторы с префиксами: 'item__hint js--item__hint', но с возможностями современных фреймворков, лучше и удобней отказаться от сверки с DOM селекторами и повесть разные слушатели на разные элементы.
    Ответ написан
    3 комментария
  • Много маленьких запросов к REST API или один большой?

    rockon404
    @rockon404
    Frontend Developer
    Если у вас сейчас что-то вроде этого:
    GET '/posts/slug/'
    
    {
      post: { /* ... */ }
    }
    
    GET '/posts/slug/comments/'
    
    {
      comments: { /* ... */ }
    }
    
    GET '/posts/slug/comments/users/'
    
    {
      users: { /* ... */ }
    }
    
    GET '/posts/slug/author/'
    
    {
      author: { /* ... */ }
    }
    
    GET '/posts/slug/meta/'
    
    {
      meta: { /* ... */ }
    }


    то логично все связанные данные объединить в один запрос:
    GET '/posts/slug/'
    
    {
      post: { /* ... */ },
      linked: {
        users: { /* ... */ },
        comments: { /* ... */ },
        meta: { /* ... */ },
      },
    }
    Ответ написан
    Комментировать
  • Как включить видео с youtube поверх всех остальных открытых окон?

    rockon404
    @rockon404
    Frontend Developer
    Установить Opera. Там есть специальная кнопка, по нажатию на которую любое видео открывается поверх всех окон во всплывающем окне.
    spoiler
    download?id=eOzONCjxGoesZuUz3asst67LxxSS
    Ответ написан
    Комментировать
  • Как в зависимости от роута React App менять глобальный redux store?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    По-хорошему, разделить приложение на две части и в каждой определить свой store.
    Но вам ничто не мешает использовать неограниченное количество store в одном приложении:

    Пример 1:
    const store1 = configureStore1();
    const store2 = configureStore2();
    
    const App = () => (
      <>
        <Provider store={store1}>
          <MainProject />
        </Provider>
        <Provider store={store2}>
          <SubProject />
        </Provider>
      </>
    );


    Пример 2:
    const store1 = configureStore1();
    const store2 = configureStore2();
    
    const App = () => (
      <Provider store={store1}>
        <>
          <MainProject />
          <Provider store={store2}>
            <SubProject />
          </Provider>
        </>
      </Provider>
    );


    C роутингом пример будет немного сложней, но суть от этого не поменяется.
    Ответ написан
  • В чем ошибка при установке приложения React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    sudo chown -R $USER:$GROUP ~/.npm
    Ответ написан
    Комментировать
  • Если props меняются, каким образом я могу дать начальное значение, чтобы избежать эффекта анти-паттерна?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Думаю тут правильней использовать useEffect:
    function Y({ x }) {
      const [y, setY] = useState(x);
      useEffect(() => {
        if (x !== y) {
          setY(x);
        }
      }, [x, y]);
    
      return ( ... );
    }

    useMemo лучше использовать для расчетов основанных на props, возврата колбеков, использующих, какой-нибудь debounce, но не для изменения состояния во время отрисовки.
    Ну и главное, что библиотека может в любой момент забыть меморизированное значение и пересчитать его заново, о чем есть примечание в документации. Так вы можете потерять текущее состояние.
    Третий вариант это использование классовых компонентов и методов жизненного цикла.
    Ответ написан
  • Какие версии redux и react-redux использовать для react 16.2.0?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Ставить пятую версию react-redux.
    Ответ написан
    Комментировать
  • Как структурировать данные?

    rockon404
    @rockon404
    Frontend Developer
    selectedAcc.children = selectedArr;

    Если массив уже существует и надо его дополнить:
    selectedAcc.children.push(...selectedArr);
    или:
    selectedAcc.children = selectedAcc.children.concat(selectedArr);
    Ответ написан
    Комментировать
  • Как из node.js эмитить через socket.io данные из ответа с интервалами?

    rockon404
    @rockon404
    Frontend Developer
    Вероятно, это нужно делать как-то по другому. Но я не приложу ума как это сделать

    Вы сейчас, наверное, будете сильно удивлены, но для соединения с помощью Socket.IO, надо подключить и использовать библиотеку Socket.IO.

    Изучить вопрос самостоятельно можно по этой ссылке.

    Ошибка у вас из-за неправильного использования setInterval, вы вместо колбека передаете туда результат выполнения send.

    Вместо:
    setInterval(foo(bar), duration);

    Надо:
    setInterval(() => {
      foo(bar);
    }, duration);


    Ну и для возможности остановить его выполнение его надо хранить и чистить по определенному условию:
    const interval = setInterval(() => {
      foo(bar);
      if (someCondition()) {
        clearInterval(interval);
      }
    }, duration);
    Ответ написан
    2 комментария
  • Как написать вкладки Accordion на React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Ваш код с парой исправлений:
    const TabContent = ({ content }) => (
      <div className="accordion">
        <p>{content}</p>
      </div>
    );
    
    function Tabs({ items }) {
      /* (1) Добавлено значение по-умолчанию для активной вкладки */
      const [active, setActive] = React.useState(0);
      
      /* (2) Хандлер по-хорошему не должен ничего возвращать */
      const openTab = e => {
        setActive(+e.target.dataset.index);
      };
    
      return (
        <div>
          <div className="tab">
            {items.map((n, i) => (
              <button
                /* (3) Добавлено свойство key */
                key={i}
                className={`tablinks${i === active ? ' active' : ''}`}
                onClick={openTab}
                data-index={i}
              >
                {n.title}
              </button>
            ))}
          </div>
          {items[active] && <TabContent {...items[active]} />}
        </div>
      );
    }
    
    /* (4) Добавлено свойство title для каждого пункта */
    /* (5) Добавлены открывающие кавычки для значений content */
    const items = [
      {
        title: 'First',
        content:
          '1. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
      },
      {
        title: 'Second',
        content:
          '2. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
      },
      {
        title: 'Third',
        content:
          '3. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
      }
    ];
    
    ReactDOM.render(<Tabs items={items} />, document.getElementById('app'));
    Ответ написан
    Комментировать
  • Есть какой-то общий store для клиента на js?

    rockon404
    @rockon404
    Frontend Developer
    Ответ написан
    Комментировать
  • Не пойму как выбрать только один checkbox?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вам надо хранить состояние массива чекбоксов и в обработчике изменять только состояние чекнутого.
    Обработка нескольких элементов Input
    пример
    import React, { Component } from "react";
    
    class Filters extends Component {
      state = {
        form: [
          { label: "Все", name: "all", value: -1 },
          { label: "Яблоко", name: "apple", value: 0, checked: true },
          { label: "Груша", name: "pear", value: 1, checked: true },
          { label: "Арбуз", name: "watermelon", value: 2, checked: true },
          { label: "Абрикос", name: "apricot", value: 3, checked: true }
        ]
      };
    
      onHandleChange = e => {
        const { checked, name } = e.target;
        const { form } = this.state;
        const index = form.findIndex(item => item.name === name);
        const item = form[index];
        const newForm = [...form];
        newForm[index] = { ...item, checked };
    
        this.setState({ form: newForm });
      };
    
      render() {
        return (
          <div className="filters">
            <div className="stops-quantity">
              <p className="currency__name">Выбрать</p>
              {this.state.form.map(item => (
                <div className="check" key={item.name}>
                  <input
                    className="stops__checked"
                    type="checkbox"
                    name={item.name}
                    value={item.value}
                    checked={item.checked}
                    onChange={this.onHandleChange}
                  />
                  <label className="stops__label" htmlFor="check1">
                    {item.label}
                  </label>
                </div>
              ))}
            </div>
          </div>
        );
      }
    }
    
    export default Filters;
    Ответ написан
  • Как сохранить выбранные checkbox после перезагрузки страницы?

    rockon404
    @rockon404
    Frontend Developer
    Пробовал реализовать через LocalStorage, но что-то идёт не так, и после перезагрузки выбранные даты пропадают.

    Неправильно пробовали. Пробуйте еще раз.

    При выборе даты:
    1. Занести значение в localStorage

    При инициализации:
    1. Проверить наличие сохраненной даты в localStorage
    2. При наличии, обновить календарь.

    Мой код

    И где тут использование loacalStorage?
    Ответ написан
    1 комментарий
  • Vue.js/Express.js :: Как правильно передавать токен на сервер в заголовках?

    rockon404
    @rockon404
    Frontend Developer
    Например так:
    headers: {
      'Content-type': 'application/json',
      'Authorization': `Bearer ${token}`,
    },

    или можно, при получении токена, занести Authorization в заголовки по-умолчанию:
    axios.defaults.headers.common.Authorization = `Bearer ${token}`;
    Ответ написан
    3 комментария
  • JavaScript не меняет css.Чт делать?

    rockon404
    @rockon404
    Frontend Developer
    Ответ написан
    Комментировать
  • This - undefined в стрелочной функции?

    rockon404
    @rockon404
    Frontend Developer
    const flipCard = e => {
      const card = e.currentTarget;
      card.classList.add('flip');
      // ...
    };
    Ответ написан
  • Как отобразить img в props компонента?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    props принято называть в camelCase. Вместо ProjectView, свойство следует назвать projectView или вообще сократить до view(или img).
    <NewSubProject img={require('../images/github-brands.svg')}
    Ответ написан
  • По какому принципу взаимодействия с сервером работает React js?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    По какому принципу взаимодействия с сервером работает React?

    По протоколу HTTP поверх TCP/IP

    Т.е есть запущенный Реакт, и этот реакт сам по себе там работает и обменивается с сервером данными через ajax запросы?

    React приложение выполняется браузером и наличие сервера не является обязательным условием. Ajax запросы как вариант.

    Т.е React работает на npm

    npm это пакетный менеджер на нем ничего не работает.

    Не могу точнее объяснить ибо не особо знаю реакт.

    Тут скорей сказываются недостаточные знания всех областей.
    Ответ написан
    Комментировать