Задать вопрос
Ответы пользователя по тегу React
  • Как правильно удалять параметры из url-строки в react-router-dom?

    0xD34F
    @0xD34F Куратор тега React
    const toggleSearchParams = params => {
      const newSearchParams = [...searchParams];
    
      for (const n of params) {
        const index = newSearchParams.findIndex(m => n[0] === m[0] && n[1] === m[1]);
        if (index === -1) {
          newSearchParams.push(n);
        } else {
          newSearchParams.splice(index, 1);
        }
      }
    
      setSearchParams(newSearchParams);
    };
    
    const handleChangeCheckBoxValue = e => {
      toggleSearchParams([ [ 'selected', e.target.value ] ]);
    };
    
    const handleDeleteParams = () => {
      toggleSearchParams(checkboxParams.map(n => [ 'selected', n ]));
    };
    Ответ написан
    Комментировать
  • Как реализовать фильтрацию с помощью checkbox?

    0xD34F
    @0xD34F Куратор тега React
    как вернуть к первоначальному состоянию когда unchecked не понимаю

    Очевидно, устанавливать в качестве результата фильтрации не его текущее значение, а полные данные.

    Ну и ещё неплохо бы сделать так, чтобы фильтрация по введённой строке не отменяла фильтрацию по чекбоксу - унесите их в один общий эффект, чтобы они работали совместно:

    function Posts() {
      const [ posts, setPosts ] = useState([]);
      const [ filteredPosts, setFilteredPosts ] = useState([]);
      const [ search, setSearch ] = useState('');
      const [ checkbox, setCheckbox ] = useState(false);
    
      useEffect(() => {
        axios
          .get('https://jsonplaceholder.typicode.com/posts')
          .then(r => setPosts(r.data));
      }, []);
    
      useEffect(() => {
        let filtered = posts;
    
        if (search) {
          const s = search.toLowerCase();
          filtered = filtered.filter(n => n.title.toLowerCase().includes(s));
        }
    
        if (checkbox) {
          filtered = filtered.filter(n => n.userId === 10);
        }
    
        setFilteredPosts(filtered);
      }, [ posts, search, checkbox ]);
    
      return (
        <>
          <input
            type="text"
            placeholder="Search for article..."
            value={search}
            onChange={e => setSearch(e.target.value)}
          />
          <label>
            User Id 10
            <input
              type="checkbox"
              checked={checkbox}
              onChange={e => setCheckbox(e.target.checked)}
            />
          </label>
    
          <ul>
            {filteredPosts.map(n => (
              <li key={n.id}>
                <div>{n.userId}</div>
                <div>{n.title}</div>
                <div>{n.body}</div>
              </li>
            ))}
          </ul>
        </>
      );
    }
    Ответ написан
    1 комментарий
  • Как замапить такую сетку?

    0xD34F
    @0xD34F Куратор тега React
    Так же, как и обычный список:

    {items.map(n => <div className="item">...</div>)}

    Увеличенную ширину задать через css:

    .item:nth-child(6n + 3),
    .item:nth-child(6n + 4) {
      ...
    }

    https://jsfiddle.net/exfk10Ls/1/
    Ответ написан
    1 комментарий
  • Как управиться с пару modal-окнами на странице?

    0xD34F
    @0xD34F Куратор тега React
    Вместо логического значения пусть будет идентификатор окна, которое надо открыть:

    <button onClick={() => setModal('раз окно')}>1</button>
    <button onClick={() => setModal('два окно')}>2</button>
    <button onClick={() => setModal('три окно')}>3</button>
    ...
    <Modal display={modal === 'раз окно'}>...</Modal>
    <Modal display={modal === 'два окно'}>...</Modal>
    <Modal display={modal === 'три окно'}>...</Modal>
    Ответ написан
    Комментировать
  • Какие самые простые учебники или курсы по React js?

    0xD34F
    @0xD34F Куратор тега React
    Подскажите самые простые учебники / статьи / видео курсы по React, где нормальным языком доступно объясняется.

    Документация.

    На офф сайте читал и мануалы и практическое руководство, тяжело очень дается и порой не понтно что к чему и зачем.

    Значит, рано за react взялись. Это ОЧЕНЬ простая вещь - конечно, для тех, кто готов её осваивать.

    фразы оттуда навроде "Подъём состояния в родительский компонент — обычное дело при рефакторинге React-компонентов." лишь отпугивают новичков вроде меня

    Вот это хорошо. Новичкам react ни к чему.

    C javascript знаком на базовом уровне

    Этого мало.
    Ответ написан
    Комментировать
  • Почему нет данных, полученных через fetch (React)?

    0xD34F
    @0xD34F Куратор тега React
    Вопрос бессмысленный, данные есть.

    fetch('https://jsonplaceholder.typicode.com/todos/1')

    Указывая id, вы получаете один объект. Объект, а не массив. Уберите 1.

    const [data, setData] = useState(null);

    {data.map(item => (

    Бывает ли у null метод map? - погуглите, разберитесь. Ну и замените null на [].
    Ответ написан
    Комментировать
  • Как в React создать два зависимые инпута типа range (slider) с неровным шагом?

    0xD34F
    @0xD34F Куратор тега React
    Сложить допустимые значения второго инпута в массив:

    const values = [ 2, 3, 5, 7, 11, 13, 17, 19, ... ];

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

    useEffect(() => {
      const index = values.indexOf(граничное_значение_второго_инпута);
    
      setVal2(values
        .slice(...(val1 > граничное_значение_первого_инпута ? [ index ] : [ 0, index ]))
        .reduce((val, n) => Math.abs(val - val2) < Math.abs(n - val2) ? val : n)
      );
    }, [ val1, val2 ]);

    https://jsfiddle.net/recx8j6w/
    Ответ написан
    1 комментарий
  • Как задавать id новым элементам массива?

    0xD34F
    @0xD34F Куратор тега React
    Взять максимальный из существующих, добавить единицу:

    1 + Math.max(0, ...articles.map(n => n.id))

    Или сделать функцию, которая будет возвращать +1 относительно результата предыдущего вызова:

    const getId = (() => {
      let id = 0;
      return () => ++id;
    })();
    Ответ написан
    3 комментария
  • Как в react работать с событием ресайза и как при загрузке определить ширину экрана и поменять стейт?

    0xD34F
    @0xD34F Куратор тега React
    onResize = () => {
      this.setState(() => ({
        /* ... */
      }));
    }
    
    componentDidMount() {
      window.addEventListener('resize', this.onResize);
      this.onResize();
    }
    
    componentWillUnmount() {
      window.removeEventListener('resize', this.onResize);
    }

    https://jsfiddle.net/jmz39vwo/
    Ответ написан
  • Как получить данные элемента по клику в итерации?

    0xD34F
    @0xD34F Куратор тега React
    onChange = {(event, userItem)=>handleChange(event, userItem)}

    Убрать userItem из списка параметров: onChange={e => handleChange(e, userItem)}.

    Или, onChange={handleChange.bind(userItem)},

    function handleChange(e) {
      console.log('userItem', this);
      console.log('value', e.target.value);
    }
    Ответ написан
    Комментировать
  • Как сделать рендер таблицы React js?

    0xD34F
    @0xD34F Куратор тега React
    Функция группировки массива по значениям одного из свойств его элементов, она нам ниже не раз понадобится:

    const group = (arr, key) =>
      arr.reduce((acc, n) => (
        (acc[n[key]] = acc[n[key]] || []).push(n),
        acc
      ), {});

    Имена свойств группируемых данных, они тоже понадобятся:

    const groupItemKeys = [ 'kurs', 'contract', 'credit' ];

    Вариант раз - выводим значения группы в одной ячейке, то, что, судя по показанному коду, пытались изобразить вы:

    const groupedData = useMemo(() => {
      return Object.entries(group(data, 'country'));
    }, [ data ]);

    <tbody>{groupedData.map(([ country, items ], i) =>
      <tr>
        <td>{i + 1}</td>
        <td>{country}</td>
        {groupItemKeys.map(k =>
          <td>{items.map(n => <div>{n[k]}</div>)}</td>
        )}
      </tr>)}
    </tbody>

    Вариант два - разбиваем данные группы по разным строкам. Для нулевого элемента группы выводим ячейки с данными, общими для группы, этим ячейкам задаём атрибут rowspan со значением, равным размеру группы:

    const groupedData = useMemo(() => {
      return Object.values(group(data, 'country'));
    }, [ data ]);

    <tbody>{groupedData.map((n, i) => n.map((m, j) =>
      <tr>
        {!j && <React.Fragment>
          <td rowSpan={n.length}>{i + 1}</td>
          <td rowSpan={n.length}>{m.country}</td>
        </React.Fragment>}
        {groupItemKeys.map(k => <td>{m[k]}</td>)}
      </tr>))}
    </tbody>

    Вариант три - сгруппированные данные разворачиваем обратно в общий массив, дополнив их значениями для атрибута rowspan и отбросив ключи, а при рендере - никаких проверок, никаких обращений к конкретным свойствам:

    const rowsData = useMemo(() => {
      return Object
        .values(group(data, 'country'))
        .flatMap((items, i) => items.map((n, j) => (j
          ? []
          : [ i + 1, n.country ].map(m => [ m, items.length ])
        ).concat(groupItemKeys.map(k => [ n[k] ]))));
    }, [ data ]);

    <tbody>{rowsData.map(n =>
      <tr>{n.map(m => (
        <td rowSpan={m[1]}>{m[0]}</td>))}
      </tr>)}
    </tbody>
    Ответ написан
    Комментировать
  • Как передать функцию, чтобы заработал онклик в react?

    0xD34F
    @0xD34F Куратор тега React
    const Figure = ({ type, ...props }) => <div className={type} {...props}></div>;
    
    class App extends React.Component {
      state = {
        types: [ 'circle', 'square', 'triangle' ],
        figures: [],
      }
    
      add(type) {
        this.setState(({ figures }) => ({
          figures: [ ...figures, type ],
        }));
      }
    
      render() {
        const { types, figures } = this.state;
    
        return (
          <div>
            <div>
              {types.map(n => <Figure type={n} onClick={() => this.add(n)} />)}
            </div>
            <div>
              {figures.map(n => <Figure type={n} />)}
            </div>
          </div>
        );
      }
    }
    Ответ написан
    6 комментариев
  • Как из компонента Child добавить родителю нужный класс?

    0xD34F
    @0xD34F Куратор тега React
    Так делать не принято, и вам это не нужно.

    Раз у всех этих элементов должен быть один класс, это должны быть корневые элементы экземпляров компонента Preloader. Тэг можно передать через props, как и те элементы, что сейчас являются соседними:

    function Preloader({ Tag = 'h1', children }) {
      return (
        <Tag className={s.wrapper}>
          <div className={s.preloader}></div>
          {children}
        </Tag>
      );
    }

    <div className="App">
      <Preloader>hello, world!!</Preloader>
      <Preloader Tag="h2">fuck the world</Preloader>
    </div>
    Ответ написан
    1 комментарий
  • Как сделать, чтобы одновременно был открыт только один элемент аккордеона?

    0xD34F
    @0xD34F Куратор тега React
    const AccordionItem = ({ title, opened, toggle, children }) => (
      <div>
        <button onClick={toggle}>{title}</button>
        {opened && children}
      </div>
    );
    
    const Accordion = ({ items }) => {
      const [ opened, setOpened ] = useState(null);
    
      return (
        <div>
          {items.map((n, i) => (
            <AccordionItem
              title={n.title}
              opened={i === opened}
              toggle={setOpened.bind(null, i === opened ? null : i)}
            >
              <p>{n.text}</p>
            </AccordionItem>
          ))}
        </div>
      );
    };
    Ответ написан
    Комментировать
  • Почему TypeError: this.props.addProduct is not a function?

    0xD34F
    @0xD34F Куратор тега React
    Что передаётся в компонент AddProductForm:

    AddProduct={this.props.addProduct}

    Как вы пытаетесь переданное использовать:

    this.props.addProduct(product);

    Правда считаете, что между "a" и "A" разницы нет?
    Ответ написан
    1 комментарий
  • Как сделать так, чтобы при смене селекта менялось состояние чекбокса?

    0xD34F
    @0xD34F Куратор тега React
    state = {
      value: 0,
      options: [ 'Не отмечено', 'Отмечено' ],
    }
    
    onChange = ({ target: t }) => {
      this.setState(() => ({
        value: +t[t.dataset.stateAttr],
      }));
    }
    
    render() {
      const { value, options } = this.state;
    
      return (
        <div>
          <select
            value={value}
            onChange={this.onChange}
            data-state-attr="value"
          >
            {options.map((n, i) => <option value={i}>{n}</option>)}
          </select>
          <br />
          <label>
            <input
              type="checkbox"
              checked={value}
              onChange={this.onChange}
              data-state-attr="checked"
            />
            {options[value]}
          </label>
        </div>
      );
    }
    Ответ написан
    Комментировать
  • Как отрисовать компонент CircleTopik только в среднем компоненте Card?

    0xD34F
    @0xD34F Куратор тега React
    function Card(props) {
      return (
        <div>
          {props.children}
        </div>
      );
    }
    
    function App() {
      return (
        <div>
          <Card />
          <Card>
            <CircleTopik />
          </Card>
          <Card />
        </div>
      );
    }

    или

    function Card({ showCircle }) {
      return (
        <div>
          {showCircle ? <CircleTopik /> : null}
        </div>
      );
    }
    
    function App() {
      return (
        <div>
          <Card />
          <Card showCircle />
          <Card />
        </div>
      );
    }
    Ответ написан
    Комментировать
  • Почему не вызывается второй аргумент внутри React.memo()?

    0xD34F
    @0xD34F Куратор тега React
    Открываем документацию и видим, что

    React.memo затрагивает только изменения пропсов. Если функциональный компонент обёрнут в React.memo и использует useState, useReducer или useContext, он будет повторно рендериться при изменении состояния или контекста.
    Ответ написан
    Комментировать
  • Почему компонент не перерисовывается?

    0xD34F
    @0xD34F Куратор тега React
    Вызов switchPatternTable внутри обработчика клика - зачем он там? Да ещё и результат улетает в никуда.

    Вызов switchPatternTable в "нужном участке страницы" - во-первых, параметр не передаётся, т.е., результат всегда будет один и тот же; во-вторых, из показанного огрызка неясно, что с этим результатом происходит дальше.

    Как бы мог выглядеть рабочий код (вам на подумать - как добавить сюда дефолтный вариант).
    Ответ написан
    Комментировать