Задать вопрос
  • Как лучше сделать черновик?

    v3shin
    @v3shin
    Веб-шаман
    События всплывают, поэтому можно повесить событие change на форму и сохранять значения полей при каждом изменении.
    document.querySelector('#myForm').addEventListener('change', function(e) {
        console.log(e.target);
    });
    Ответ написан
    Комментировать
  • Как правильно обработать ссылки из google docs?

    yarkov
    @yarkov Куратор тега JavaScript
    Помог ответ? Отметь решением.
    Вместо textarea юзайте div с contenteditable
    Ответ написан
    Комментировать
  • Нужно ли указывать заголовок Content-Type: form/multipart прии отправке формы?

    @alexalexes
    https://ru.wikipedia.org/wiki/Multipart/form-data
    Есть работа с отправкой файлов?
    - Есть. нужен заголовок.
    - Нет, тогда не нужен заголовок.
    Ответ написан
    Комментировать
  • Как изменить url без записи в history?

    Lynn
    @Lynn
    nginx, js, css
    Ответ написан
    Комментировать
  • Как убрать перевернутый экран на Ubuntu?

    toxa82
    @toxa82
    Выключить акселерометр/гироскоп
    echo 'blacklist hp_accel' | sudo tee /etc/modprobe.d/blacklist-self.conf
    sudo rmmod hp_accel
    Ответ написан
    Комментировать
  • Как правильно использовать hook useEffect?

    profesor08
    @profesor08 Куратор тега JavaScript
    Во первых, useEffect сработает всегда, при рендере компонента. Обновилс просы или стейт, и будь уверен, useEffect будет вызван. Это значит, что тебе надо ввести внутренний стейт для компонента, обозначающий, что он отобразился.
    const Comp = () => {
      const [ready, setReady] = useState(false);
      const dispatch = useDispatch();
    
      useEffect(() => {
        if (ready === false) { // после отображения элемента будет вызвана функция, `ready` все еще будет `false`, поэтому выполнив свой код, надо вручную задать ей true, чтоб код не вызывался дважды.
          dispatch({ type: 'increment-counter' });
          setReady(true);
        }
      });
    };


    В ошибке тебя просят убрать `[]` из вызова useEffect

    Как использовать хуки в redux написано тут, с примерами:
    https://react-redux.js.org/next/api/hooks
    Ответ написан
  • Как решить проблему net::ERR_ADDRESS_INVALID?

    @kolyosik
    по умолчанию server side хостится на "0.0.0.0"
    для нормальной работы требуется при запуске явно указать хост
    для этого в `package.json` нужно добавить скрипт
    "start": "set \"HOST=localhost\" && react-ssr-scripts start",
    Ответ написан
    Комментировать
  • Как анимировать list в React?

    freislot
    @freislot
    Frontend-разработчик
    Ставишь пакет
    npm install react-transition-group

    Импортируешь
    import { TransitionGroup, CSSTransition } from "react-transition-group";

    Анимируешь
    <TransitionGroup className="items-section__list">
      {list.map(elem => (
        <CSSTransition key={elem} timeout={500} classNames="move">
          <h5 key={elem}>{elem}</h5>
        </CSSTransition>
      ))}
    </TransitionGroup>

    Добавляешь css по вкусу
    .move-enter {
      opacity: 0.01;
      transform: translate(-40px, 0);
    }
    
    .move-enter-active {
      opacity: 1;
      transform: translate(0, 0);
      transition: all 500ms ease-in;
    }
    
    .move-exit {
      opacity: 1;
      transform: translate(0, 0);
    }
    
    .move-exit-active {
      opacity: 0.01;
      transform: translate(40px, 0);
      transition: all 500ms ease-in;
    }

    Обновленный пример из вопроса

    PS если нравится принцип анимирования через жизненные циклы, то никто не мешает в функциональных компонентах использовать хуки, почти то же самое. Попробуй.
    Вот тебе наводка Super easy react mount/unmount animations with hooks
    Ответ написан
    Комментировать
  • Полноценный пример SSR для react/redux?

    Да состояние собирается на сервере для каждого клиента (request'a), скажем на уровне мидлвара мы собираем состояние (текущего авторизованного пользователя, какие-то другие глобальные данные), далее отрабатывает обработчик маршрута, мы получили данные какой-то страницы из бд и передали их как контекст, примерно так:
    import React from 'react';
    import { StaticRouter } from 'react-router'
    import { Provider } from 'react-redux'
    import ReactDOMServer from 'react-dom/server';
    
    import App from './client/components/App.jsx'
    
    ReactDOMServer.renderToString(
    	<Provider store={ReduxStore}>
    		<StaticRouter
    			location={Url}
    			context={Context}>
    			<App/>
    		</StaticRouter>
    	</Provider>
    );

    Где, ReduxStore сгенерированное нами глобальное состояние (redux) запроса, Url запрошенный урл, Context контекст (будет передано как this.props.staticContext в компонент). Реакт вытянет нужный контейнер роута (по вашим маршрутам в App) и передаст ему контекст, компонент рендерится исходя из полученных данных. Результатом работы метода renderToString будет html строка (размеченная реактом), которую мы шаблонизатором или как угодно впиливаем в блок моунта компонента (в верстке), дополнительно в шаблонизатор передаем сгенерированное состояние, в документации выглядит вот так:
    window.__PRELOADED_STATE__ = JSON.stringify(preloadedState || {}).replace(/</g, '\\u003c')

    Теперь что происходит после того как страница загрузилась и подхватились клиент-скрипты? Все просто мы подхватываем состояние из window.__PRELOADED_STATE__ и вообщем-то все, глобальное состояние передано, компонент уже отрендерен, стоит учитывать что результаты при клиент-рендере и при сервер-рендере должны быть всегда одинаковыми, так же не использовать методы доступные браузеру, но не доступные серверу (на уровне моунта и первого рендера) и хорошенько следить за своим кодом в плане памяти, иначе при какой-либо утечке, память на сервере не будет вычищаться после каждого рендера.
    ---
    Как-то так, надеюсь помог, хотя там еще довольно много заковык
    Ответ написан
    20 комментариев
  • Как создать и скачать файл на фронте?

    hzzzzl
    @hzzzzl


    см строчки

    element.setAttribute('href', 'data:text/plain;charset=utf-8,' + text);
    element.setAttribute('download', 'file.csv');
    Ответ написан
    Комментировать