Ответы пользователя по тегу React
  • Делают ли так в Reacte?

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

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

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

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Читаем документацию.
    Ответ написан
    Комментировать
  • Хранение данных в Redux?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Данные, полученные с API, принято хранить в store redux, так как единый подход к организации кодовой базы повышает удобство ее сопровождения. Но никто не запрещает вам делать иначе.
    Ответ написан
    Комментировать
  • Как сохранить state компонента React при его повторном рендере?

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

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Первый вариант будет лучше если у вас форма и компонентов много. Можно обрабатывать все одним хандлером:
    const handler = (e) => {
      const { target } = e;
      const value = target.type === 'checkbox' ? target.checked : target.value;
      const { name } = target;
    
      setForm( f => ({ ...f, [name]: value }));
    };

    Второй, если checkbox один и приложение должно как-то реагировать на его изменение. Но хандлер для лучшей читаемости, лучше вынести в переменную. Если это built-in компонент вроде input:
    const handler = () => {
      setX(!x);
    };

    И если это кастомный компонент, то необходимо использовать useCallback, чтобы предотвратить лишние перерисовки:
    const handler = useCallback(() => {
      setX(!x);
    }, []);

    Ну и неконтролируемые компоненты, упомянутые Алексей Николаев, в ряде кейсов могут быть очень удобны.
    Ответ написан
    Комментировать
  • Как обойти бессмысленную проверку array.filter?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    spoiler

    import React, { Fragment, useCallback, useState } from "react";
    import ReactDOM from "react-dom";
    
    const arrProd = [
      {
        price: "5.75",
        sold: "100"
      },
      {
        price: "2.36",
        sold: "15"
      },
      {
        price: "5.48",
        sold: "20"
      },
      {
        price: "4.49",
        sold: "200"
      },
      {
        price: "3.15",
        sold: "258"
      },
      {
        price: "9.99",
        sold: "479"
      },
      {
        price: "4.8",
        sold: "147"
      },
      {
        price: "8",
        sold: "951"
      },
      {
        price: "4.27",
        sold: "753"
      },
      {
        price: "2.46",
        sold: "852"
      },
      {
        price: "4.99",
        sold: "742"
      },
      {
        price: "3.49",
        sold: "10"
      },
      {
        price: "2",
        sold: "26"
      },
      {
        price: "3.83",
        sold: "39"
      },
      {
        price: "9.98",
        sold: "47"
      },
      {
        price: "6.77",
        sold: "96"
      }
    ];
    
    function App() {
      const [form, setForm] = useState({
        minPrice: "",
        maxPrice: "",
        sold: ""
      });
    
      const { minPrice, maxPrice, sold } = form;
    
      const [products, setProducts] = useState(arrProd);
    
      const handleChange = useCallback(e => {
        const { name, value } = e.target;
        setForm(f => ({ ...f, [name]: value }));
      }, []);
    
      const handleSubmit = useCallback(
        e => {
          e.preventDefault();
    
          const filteredProducts = arrProd.filter(
            product =>
              (!maxPrice || +maxPrice >= +product.price) &&
              (!minPrice || +minPrice <= +product.price) &&
              (!sold || +sold >= +product.sold)
          );
    
          setProducts(filteredProducts);
        },
        [minPrice, maxPrice, sold]
      );
    
      const isPriceRangeValid = !minPrice || !maxPrice || +minPrice <= +maxPrice;
      const isSoldValid = +sold >= 0;
    
      return (
        <Fragment>
          <form onSubmit={handleSubmit}>
            {!isPriceRangeValid && <div>"Please provide a valid price range"</div>}
            Min
            <input
              type="text"
              name="minPrice"
              size={6}
              maxLength={10}
              value={minPrice}
              onChange={handleChange}
            />
            Max
            <input
              type="text"
              name="maxPrice"
              size={6}
              maxLength={10}
              value={maxPrice}
              onChange={handleChange}
            />
            {!isSoldValid && <div>Please provide a valid sold value</div>}
            Sold
            <input
              type="text"
              name="sold"
              size={6}
              maxLength={10}
              value={sold}
              onChange={handleChange}
            />
            <input type="submit" title={"Submit price range"} value={"Go"} />
          </form>
          <ul>
            {products.map((product, i) => (
              <li key={product.sold + i}>
                {product.price} - {product.sold}
              </li>
            ))}
          </ul>
        </Fragment>
      );
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);

    Проверки на валидность просто для демонстрации.
    Ответ написан
    2 комментария
  • Переход к первому незаполненному полю при ошибке валидации формы React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Ну сделайте через ref или как считаете лучше. Тут не принципиально, лишь бы было удобно добавлять и удалять поля при необходимости.
    Ответ написан
    Комментировать
  • Как запустить метод ребёнка из родителя?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Часто в таких кейсах применяют render props:
    return (
      <ModalWrapper
        body="Body text"
        isProcessing={isFetching}
        onConfirm={this.handleConfirm}
      >
        {openModal => (
          <Button onPress={openModal}>
            Some dangerously action
          </Button>
        )}
      </ModalWrapper>
    );
    Ответ написан
    Комментировать
  • Как завершить работу компонента React?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Я вам уже писал про роутинг. Посмотрите этот пример.
    Если точно уверены, что роутинг вам не нужен, то используйте условный рендеринг.
    Ответ написан
    2 комментария
  • Node JS насколько удобен в Desktop и для сайтов?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    React и Node.js это разные вещи.
    Почитайте документацию к Electron. Это будет ответом на все ваши вопросы.
    Ответ написан
    Комментировать
  • Передача нового массива для каждого компонента?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    1. Убирайте массивы arrayTitleTask и miniTasksArray. Работайте с состоянием компонентов.
    2. У каждой titleTask должен быть свой массив miniTasks.
    3. Почитайте про иммутабельность и иммутабельное обновление состояния.
    Ответ написан