Задать вопрос
Ответы пользователя по тегу React
  • Передача анонимной функции в компонент?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Помимо создания функции, которое само по себе не такая затратная операция, в компонент каждую перерисовку будет приходить новая ссылка, что при сравнении свойств вызовет его обновление.
    Читаемость кода с таким подходом так же хуже.

    Определяйте хандлеры в классовых компонентах свойствами класса, а в функциональных используйте хук useCallback.

    Реальную разницу в производительности вы можете замерить с помощью бенчмарков и вкладок Performance и React Profiler в Dev Tools.

    Что касается хранения состояния форм в redux, то в большинстве случаев в этом нет необходимости.

    Насколько я понял, вы хотите использовать анонимные функции, потому что у вас возникли проблемы с определением имени обновляемого свойства в колбеке. Решение этой задачи:
    const Example = () => {
      const [order, setOrder] = useState({
        building: '',
        otherProp: '',
      });
    
      const handleChange = useCallback(e => {
        const { name, value } = e.target;
        setOrder(s => ({ ...s, [name]: value }));
      }, []);
    
      return (
        <Input
          name="building"
          onChange={handleChange}
          value={order.building}
        />
      );
    };

    Версия с redux

    Меняем редьюсер так, чтобы по действию updateOrder он принимал только измененные свойства и подмешивал их к старому значению order. Это позволит не добавлять зависимость в useCallback, да и вообще более правильное решение.
    const Example = () => {
      const dispatch = useDispatch();
      const order = useSelector(orderSelector);
    
      const handleChange = useCallback(e => {
        const { name, value } = e.target;
        dispatch(updateOrder({ [name]: value }));
      }, []);
    
      return (
        <Input
          name="building"
          onChange={handleChange}
          value={order.building}
        />
      );
    };

    Этот прием описан в документации:
    Обработка нескольких полей ввода
    Ответ написан
    Комментировать
  • Реактовское состояние в чистом JS?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Достаточно грубый пример, но суть должен передать:
    const updater = (component, prevState) => {
      if (Object.keys(prevState).some(
        key => prevState[key] !== component.state[key],
      )) {
        component.render();
        
        if (component.componentDidUpdate) {
          component.componentDidUpdate(prevState);
        }
      }
    }
    
    const domRender = (Component) => {
      const component = new Component();
      
      component.render();
      
      if (component.componentDidMount) {
        component.componentDidMount();
      }
    }
    
    class Component {
      constructor() {
        this.updater = updater;
      }
      
      setState(newState) {
        const prevState = this.state;
        
        if (typeof newState === 'function') {
          this.state = newState(prevState);
        } else {
          this.state  = { ...prevState, ...newState };
        }
        
        this.updater(this, prevState);
      }
    }
    
    class Example extends Component {
      constructor() {
        super();
        this.state = {
          value: 'Initial value',
        }
      }
      
      componentDidMount() {
        setTimeout(() => {
          this.setState({ value: 'New value' });
        }, 2000);
      }
    
      componentDidUpdate(prevState) {
        console.log('Prev state: ', prevState);
        console.log('New state: ', this.state);
      }
    
      render() {
        const { value } = this.state;
        
        document.querySelector('.example').innerHTML = value;
      }
    }
    
    
    domRender(Example);

    Демо
    Ответ написан
    4 комментария
  • Вопрос о ключевом слове super?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Объявление:
    class Example extends Component { ... }
    Определяет класс Example который наследуется от Compоnent.

    super(props);
    Вызов конструктора Component с передачей первым аргументом объекта props.
    Ответ написан
    3 комментария
  • Как создать ссылку на файл xml в react-router?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вам надо использовать тег a:
    <a href="/path/file_name.xml" download>Download</a>

    Если вы хотите использовать file-loader для переноса файла в статическую директорию сборки, то:
    <a href={require('../path/file_name.xml')} download>Download</a>


    react-router используется исключительно для клиентской навигации и рендера древа в зависимости от значения location.
    Ответ написан
    8 комментариев
  • Реагировать на эквивалентные хуки для ComponentWillMount Задать?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Во-первых componentWillMount не рекомендован к использованию. Во-вторых, он никак не защитит вас от дополнительного вызова render, если речь идет о выполнении асинхронной операции, а для синхронных он и не нужен.
    Смело используйте componentDidMount и useEffect.

    А от лишних вычислений можно огородиться, например, так:
    if (!someCondition) return null;
    Ответ написан
    Комментировать
  • Как определить локальную переменную в другом файле реакции?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Lifting state up
    Либо использовать state management библиотеку. Например, Redux или MobX.
    Ответ написан
    Комментировать
  • Почему не находится модуль?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    import Profile from "./Profile";
    Ответ написан
    1 комментарий
  • Как объявлять компоненты в React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Классовые компоненты никуда не уходят. Для них осталось несколько удобных кейсов. Например:
    1. Удобное получение предыдущих значений свойств и состояний в componentDidUpdate.
    2. Доступ к экземпляру компонента в хандлерах, передаваемых в браузерные API.
    3. Сложные компоненты с большим количеством методов. Например VideoPlayer.

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

    Оптимизация это отдельный вопрос, которому стоит посвятить время. Сейчас разве стоит предупредить вас, что преждевременная оптимизация - зло.

    Попробуйте использовать в коде преимущественно функциональные компоненты и хуки. Сейчас почти все популярные библиотеки имеют в API довольно удобные в использовании хуки. Там, где покажется, что будет удобней использовать класс, не бойтесь использовать классы.
    Ответ написан
    1 комментарий
  • Как правильно разложить роуты в проекте?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    <Switch>
      <Route exact path="/services" component={Services} />
      <Route exact path="/login" component={Login} />
      <Route path="/" component={Wrapper} />
    </Switch>

    NotFound надо перенести в Switch компонента Wrapper.
    Ответ написан
    3 комментария
  • Kаким лучшим способом обрабатывать error ,loading и ответить из сервера?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Логику можно вынести в собственный хук. Как-то так:
    const useFetch = (url, options) => {
    
      const [data, setData] = useState(null);
      const [error, setError] = useState(null);
      const [isLoading, setIsLoading] = useState(true);
    
      const fetchData = async () => {
        try {
          setIsLoading(true);
          const res = await fetch(url, options);
          const json = await res.json();
          setData(json);
          setIsLoading(false);
        } catch (error) {
          setError(error);
          setIsLoading(false);
        }
      };  
    
      useEffect(() => {
        fetchData();
      });
    
      return [
        data,
        isLoading,
        error,
        fetchData,
      ];
    };


    const Example = ({ slug }) => {
      const [ product, isLoading, error, fetchFn ] = useFetch(`/api/product/${slug}`);
      
      if (isLoading) return <Preloader />;
    
      if (error) return <Error error={error} tryAgainFn={fetchFn} />;
    
      if (!product) return <NotFound />;
      
      return <Product product={product} />
    };
    Ответ написан
    Комментировать
  • Как настроить относительные пути в Webpack?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    после некоторого времени обнаружил что вебпак изменяет путь
    То есть
    путь import video from '../../img/video/mainstream.mp4'
    он видит как Video /static/media/mainstream.bbae5fec.mp4

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

    Deployment

    Что касается определения пути к файлу в атрибуте тега, то с webpack это делается так:
    <video src={require('../../img/video/mainstream.mp4')} />
    Ответ написан
  • Как перекомпилировать CRA2 + Ant Design + Scss?

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

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Современные фреймворки вроде Angular/React/Vue созданы для решения одних и тех же задач. Использовать лучше тот, который больше нравится и который лучше знаете. При неумелом использовании все преимущества конкретного фреймворка меркнут, и на Vue, в таком случае, вы можете получить медленную скорость разработки, а на React неподдеживаемый код.
    Ответ написан
    Комментировать
  • Как исправить ошибки при подключении Bootstrap к react?

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

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Синтетические события нельзя использовать асинхронно, e.persist() освобождает событие из пула и оно не очищается, поэтому все значения сохраняются на момент выполнения асинхронного вызова.

    Ваша задача решалась так:
    onChange={(e) => this.limitSwitchHandler(e, row.id)}


    В вашем решении правильней назвать хандлер:
    createLimitPerDayHandler = (rowId) => (e) => { ... };

    так как технически вызов не является хандлером, а возвращает его.
    Ответ написан
    Комментировать
  • Когда я должен использовать React.FC?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Пример:
    interface Props {
      someProp: string;
    }
    
    const Herberito: React.FC<Props> = ({ someProp }) => <div>{someProp}</div>;


    Если вы не передаете внешние свойства или children, то тип React.FC можно не указывать.
    Ответ написан
    3 комментария
  • Как передать в качестве пропс другой компонент?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Рассмотрите вариант:
    const Header = ({ children }) => (
        <div className="navHeader">
          {children}
        </div>
      );


    <Header>
      <Top />
    </ Header>


    Можно еще решить как-то так:
    const Header = ({ top }) => {
      const HeaderTop = top || Top;
      
      return (
        <div className="navHeader">
          <HeaderTop />
        </div>
      );
    };

    Тогда у вас будет компонент по-умолчанию, а свойство top можно будет использовать только там, где необходимо использовать другой компонент.
    <Header /> // используем компонент по-умолчанию Top

    <Header top={OtherTopCompnent} /> // используем другой компонент
    Ответ написан
    1 комментарий
  • Почему компонент unknown?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Суть проблемы в том, что у анонимной функции пустое свойство name.
    React использует либо заданное свойство displayName, либо собственное свойство функции name. Ни одно из свойств не найдено и вы видите Unknown
    connect в свою очередь, если при создании обертки не находит одно из этих свойств использует слово Component, которое вы и видите в скобках.

    По-хорошему, компоненты описывают так:
    const MovieList: React.FC<MovieListPropsType> = ({ ... }) => { ... };
    
    const mapStateToProps = createStructuredSelector({ ... });
    
    const mapDispatchToProps = { ... };
    
    export default connect(mapStateToProps, mapDispatchToProps)(MovieList);


    P.S. у вас ошибка в слове Desktop.
    Ответ написан
    4 комментария
  • Как реализовать переключение вкладок с использованием классов вместо функций?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Посмотрите ответ на ваш прошлый вопрос. Там почти идентичный пример и пошаговая реализация в двух версиях.
    Ответ написан
  • Простые open source проекты на JS для их 'разбора'?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    React. Пишем в google:
    weather app react github,
    todo app react github,
    reddit app react github,
    etc.
    Ищем посвежее и изучаем.

    Node JS:
    chat node github,
    rest api node github,
    video editor node github,
    etc.

    Ищем посвежее и изучаем.

    JS:
    <То к чему душа лежит> github.
    Ищем посвежее и изучаем.

    Open source библиотеки - забудьте. Неподготовленному уму по ним учиться писать вредно.

    Если действительно хотите научиться писать более менее хороший код, идите работать в компанию.
    Ответ написан
    2 комментария