• Почему jQuery не находит елемент в componentDidMount()?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Почему jQuery не находит елемент в componentDidMount()

    Потому что в момент вызова вы показываете Preloader или null.

    Не стоит использовать JQuery в React разработке.
    Ответ написан
    1 комментарий
  • Как правильно структурировать реакт проект?

    Robur
    @Robur
    Знаю больше чем это необходимо
    делаете папку shared (или как больше нравится) куда складываете все что нужно использовать в разных компонентах.
    Если появляется необходимость что-то куда-то перенести - то это не "проблема", это нормально, берете и переносите, приложение поменялось - структура оптимальная уже другая.
    Ответ написан
    Комментировать
  • Как менять title с помощью React.js?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    react-helmet
    <Helmet title="My site" />
    Ответ написан
    Комментировать
  • Как найти данные в массиве?

    rockon404
    @rockon404
    Frontend Developer
    const res = a1.filter(i => a2.some(j => j.id === i.id));
    Ответ написан
    Комментировать
  • Как динамически задавать state?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    setVal = (propName, value) => {
      this.setState(state => ({
        formInfo: {
          ...state.formInfo,
          [propName]: value,
        }
      }));
    };

    Так же переименовал getval в setVal. Так как глагол get используют в функциях возвращающих значение, а set в устанавливающих значение.
    Ответ написан
    2 комментария
  • Как сделать правильно Route для id и new?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    <Switch>
      <Route exact path={`${match.url}/`} component={List} />
      <Route exact path={`${match.url}/new`} component={New} />
      <Route exact path={`${match.url}/:id`} component={View} />
    </Switch>
    Ответ написан
    3 комментария
  • Почему содержимое шляпы не меняется, когда я нажимаю на куртку?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вы передаете вторым аргументом в useEffect пустой массив. Это значит, что функция колбек будет вызвана только при монтировании компонента. Вам следует передавать в массив второго аргумента match.url, тогда колбек будет вызываться после монтирования и каждый раз при изменении url.
    const Hat = ({ match }) => {
      // ...
      useEffect(() => {
        fetch(`https://foo0022.firebaseio.com//male/hat.json`)
          .then(res => res.json())
          .then(setArrProd);
      }, [match.url]);
      // ...
    }
    Ответ написан
    Комментировать
  • Как передать ref родительскому компоненту?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    import React, { Component } from 'react';
    import Child from './Child';
    
    class Parent extends Component {
      childRef = React.createRef();
    
      render() {
        return (
          <Child innerRef={this.childRef} />
        );
      }
    }


    import React, { Component } from 'react';
    
    export default class Child extends Component {
      render() {
        const { innerRef } = this.props;
    
        return (
          <div ref={innerRef}></div>
        );
      }
    }
    Ответ написан
    1 комментарий
  • Импорт компонента в React. Почему не работает?

    tsepen
    @tsepen
    Frontend developer
    Так ты его нигде не импортируешь, напиши
    import {Footer} from './footer/footer.js'
    Ответ написан
    1 комментарий
  • Почему styled-components выдает ошибку?

    0xD34F
    @0xD34F Куратор тега React
    Attempted import error: 'CreateGlobalStyle' is not exported from 'styled-components'.

    Ясно.

    Разницу между CreateGlobalStyle и createGlobalStyle самостоятельно разглядеть сможете?
    Ответ написан
    1 комментарий
  • Как сделать, чтобы крашился только конкретный компонент, а не всё приложение?

    @DragonSpirit
    Mobile Developer
    Вообще ошибки надо бы исправлять, но можно глянуть в сторону componentDidCatch
    Ответ написан
    1 комментарий
  • Самописная CMS или Bitrix для интернет магазина?

    @glagolew059
    frontend developer
    я за битрикс
    работая с этой cms приходилось не раз переводить сайты как раз с самописных cms застрявших на каких-то этапах, хотя поначалу разработчики обещали кучу плюшек, а на деле даже до админки не доходили, и все застревало в самом начале
    Ответ написан
    Комментировать
  • Возможно ли с помощью hooks создать полноценную замену классовым компонентам?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    useEffect(() => {
      // component did mount code here
      return () => {
        // component will unmount code here
      };
    }, []);

    Почитать.
    Ответ написан
  • Подгрузка данный при помощи Аjax в React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Пагинация
    Ответ написан
    Комментировать
  • Оценка своего уровня. Как улучшить код?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Используйте const вместо let для определения переменных которые не переопределяются в коде. Это помогает снизить когнитивную нагрузку с человека читающего код и негласный стандарт в React разработке.

    2. Такие вещи как globalStyles и конфигурацию store лучше вынести в отдельные файлы. Они могут со временем хорошо разрастись.
    По поводу globalStyles, вы вообще можете вынести их в отдельный css файл.

    3. Вместо:
    {
      isModal
      ? <Route path="/auth" component={AuthPopup} />
      : null
    }

    лучше:
    {isModal && <Route path="/auth" component={AuthPopup} />}


    4. Вместо:
    function mapDispatchToProps(dispatch) {
        return {
            autoLogin: () => dispatch(autoLogin()),
            getBrowser: () => dispatch(getBrowser()),
            getMedia: () => dispatch(getMedia())
        }
    }


    лучше:
    const mapDispatchToProps = {
      autoLogin,
      getBrowser,
      getMedia,
    };


    5. Точки с запятыми в конце то есть, то нет. Определитесь и приведите код к одному виду.

    6.
    & label {}
    & input {}
    & span {}

    Это не очень хороший подход. Во-первых ваши стили не изолированные, что может приводить к неожиданным результатам. Во-вторых у вас очень много дублирования стилей. Определите Input и Label как базовые компоненты и используйте в разных местах, то же с остальным если есть.

    7. Почему папка со страницами называется Containers? Дань бойлерплейтам?

    8. Использование trailing comma является хорошей практикой.

    9.
    import {combineReducers} from 'redux';
    import photoReducer from './photoReducer';
    import authReducer from './authReducer';
    import globalReducer from './globalReducer';
    
    export default combineReducers({
        photoReducer, authReducer, globalReducer
    })


    Все таки приятней работать с хранилищем в котором ключи не имеют в названии слова reducer:
    import {combineReducers} from 'redux';
    import photo from './photoReducer';
    import auth from './authReducer';
    import global from './globalReducer';
    
    export default combineReducers({
      photo, 
      auth,
      global,
    });


    10. Забудьте вообще, что в языке есть возможность использовать вложенный тернарный оператор:
    return e === 'invalid-email' ? 'Неверно указан e-mail'
        : e === 'user-not-found' ? 'Указанный e-mail на найден'
        : e === 'wrong-password' ? 'Неверный пароль'
        : e === 'email-already-in-use' ? 'Указанный e-mail уже используется'
        : e === 'network-request-failed' ? 'Нет подключения к интернету'
        : e === 'operation-not-allowed' ? 'Произошла ошибка, попробуйте снова'
        : e === 'popup-closed-by-user' ? 'Окно авторизации закрыто пользователем'
        : e === 'account-exists-with-different-credential' ? 'Аккаунт уже существует с другими данными, используйте другой способ авторизации'
        : e

    Это одна из самых худших практик в JavaScript разработке. Тут лучше подойдет конструкция switch case

    11. Константы actionTypes лучше вынести в папку constants и разложить по разным файлам, иначе со временем у вас там будет свалка.

    12. Вместо:
    import {SET_ACTIVE, CHANGE_VALUE, SET_DEFAULT, UPLOAD, UPDATE_IMAGE, SET_IMAGE_ERROR, SET_LIKE, SET_COMMENT, ADD_ARTICLE_SUCCESS, FETCH_ARTICLES_START, FETCH_ARTICLES_SUCCESS, FETCH_ARTICLES_ERROR} from '../actions/actionTypes';

    Лучше:
    import {
      SET_ACTIVE,
      CHANGE_VALUE,
      SET_DEFAULT, UPLOAD,  
      UPDATE_IMAGE,
      SET_IMAGE_ERROR,
      SET_LIKE,
      SET_COMMENT,
      ADD_ARTICLE_SUCCESS,
      FETCH_ARTICLES_START,
      FETCH_ARTICLES_SUCCESS,
      FETCH_ARTICLES_ERROR,
    } from '../actions/actionTypes';


    13. Попробуйте внедрить библиотеку reselect. И для получения значения из store вместо записи вида:
    function mapStateToProps(state) {
        return {
            browser: state.globalReducer.browser
        }
    }


    использовать селектор:
    const mapStateToProps = state => ({
      browser: browserSelector(state),
    });
    Ответ написан
    12 комментариев
  • Манипуляции со state и несколько вопросов по рендерингу и архитектуре в реакт?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Что с именами? NewsItem, setItem, result, clickFilter, styles, buy - никогда не пишите подобного даже в шутку. Замените: NewsItem на Product(или ShopItem), setItem - вообще удалите, result на products, clickFilter на handleAddToCartClick, styles на className, buy на cart.

    2. Нет никакого смысла передавать в ShopItem каждое свойство товара по отдельности. Только усложняете анализ вашего кода. Лучше:
    {products.map(product => (
      <ShopItem
        key={product.id}
        className={'item'}
        item={product}
        onAddToCartClick={this.handleAddToCartClick}
      />
    )}


    3. Base path на то и base path, что не должен содержать конкретный эндпоинт. Правильно:
    const BASE_PATH = 'https://api.punkapi.com/v2';
    
    /* ... */
    
    fetch(`${BASE_PATH}/beers`)


    Каким образом добавить полученные "товары" в корзину? Я не смог использовать значения из state.result для последующего их добавления в state.basket.
    result это просто массив из объектов. Можно получить доступ к любому товару с помощью this.state.result[индекс_объекта], но ничего с этими данными напрямую делать у меня не получается, как и с помощью setState

    Если вы не понимаете как работать с данными(массивы, объекты), то вам стоит сейчас заострить свое внимание на изучении этого вопроса:
    JavaScript: Структуры данных
    Вам вообще нет смысла копировать товар в массив cart, туда можно складывать только id товара и количество:
    class Store extends Component {
      state = {
        products: [],
        cart:[],
      };
    
      handleAddToCartClick = (id, quantity) => {
        const { cart } = this.state;
        const itemIndex = cart.findIndex(item => item.id === id);
    
        if (itemIndex !== -1) {
          const newCart = [...cart];
          newCart[itemIndex] = { id, quantity: cart[itemIndex].quantity + quantity };
          this.setState({ cart: newCart });
        } else {
          this.setState(prevState => ({
            cart: [
              ...prevState.cart,
              { id, quantity },
            ],
          }));
        }
      };

    const ShopItem = ({ className, item, onAddToCartClick }) => (
      <div>
        {/* ... */}
        <button onClick={() => onAddToCartClick(item.id, 1)}>Добавить в корзину</button>
      <div/>
    );

    Вопрос вытекает из 1го, а нормальная ли это практика добавлять в state данные, полученные из API? Если нет, то где тогда можно их хранить?

    По-хорошему, в redux store. redux стоит использовать тут хотя бы потому, что те же данные о товарах понадобятся и в корзине, и на странице checkout.

    Я хотел создать у каждого "товара" кнопку, которая будет менять стиль КОНКРЕТНО этого товара (это не несет никакой смысловой нагрузки, но мне хотелось это реализовать чтобы понять некоторые вещи).
    У моего компонента NewsItem есть пропс styles, который устанавливает стиль в компонент.

    Самый простой вариант использовать хук useState:
    import React, { useState } from 'react';
    
    const ShopItem = ({ className, item, onAddToCartClick } ) => {
      const [isActive, setIsActive] = useState(false);
      
      handleToggleActiveClick = () => {
        setIsActive(!isActive);
      };
    
      return (
        <div>
          <ul className={`${className}${isActive ? ' active' : ''}`}>
            {/* ... */} 
            <button onClick={handleToggleActiveClick}>Toggle active</button>
          </ul>
        <div/>
      );
    }
    Ответ написан
    1 комментарий
  • Как выполнить ПОСТ запрос с параметрами бади и хэдер?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    const form = new FormData();
    form.append('key', 'ecmdecmedmjrjekrkl');
    
    fetch('/some-path', {
      method: 'POST',
      headers: "Content-Type: application/x-www-form-urlencoded",
      body: form,
    }).then(assets => this.setState({assets}, () => console.log('Fetched!')));


    По-хорошему, ваше приложение должно взаимодействовать с сервером по REST API, данные передаваться в формате JSON.

    Захардкоженный ключ доступа не лучшее решение.
    Ответ написан
    Комментировать
  • Разница между useCallback и useMemo?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Вызов useCallback(fn, deps) эквивалентен useMemo(() => fn, deps)
    Вся разница в дополнительной обертке, которую не придется писать при использовании useCallback, если надо возвращать меморизированный колбек.
    Ответ написан
    Комментировать
  • Как по клику добавить styled стили к body?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Как везде:
    document.body.classList.add('some-class');
    Ответ написан
    Комментировать
  • Как на React при изменении Route менять содержимое тега?

    hzzzzl
    @hzzzzl
    в компоненты положить это
    https://github.com/nfl/react-helmet

    <Parent>
        <Helmet>
            <title>My Title</title>
            <meta name="description" content="Helmet application" />
        </Helmet>
    
        <Child>
            <Helmet>
                <title>Nested Title</title>   // положить это
                <meta name="description" content="Nested component" /> 
            </Helmet>
        </Child>
    </Parent>
    Ответ написан
    Комментировать