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

    0xD34F
    @0xD34F Куратор тега React
    На время загрузки данных вы уничтожаете компонент пагинации, соответственно, при каждом изменении страницы он создаётся заново - поэтому его внутреннее значение текущей страницы постоянно оказывается дефолтным.

    Явно указывайте компоненту пагинации, какую страницу считать текущей (forcePage={currentPage}).

    Уберите +1 из обработчика выбора страницы, добавляйте единицу при запросе (проще подправлять значение текущей страницы в одном месте, чем в двух - так бы пришлось ещё и -1 делать при указании страницы компоненту пагинации).
    Ответ написан
    Комментировать
  • Как сделать навигацию назад-вперед при пагинации?

    0xD34F
    @0xD34F Куратор тега React
    И в чём проблема? Компонент пагинации, в котором доступна текущая страница и метод её изменения у вас уже есть. Осталось нарисовать две кнопки, которые будут вызывать onPageChange с page - 1 и page + 1.
    Ответ написан
  • Как обнулить секундомер и снова начать отсчет при кликe?

    0xD34F
    @0xD34F Куратор тега React
    Дичь какая-то - зачем вам хранить количество минут и часов? Достаточно секунд (да, их будет не 0-59, а сколько угодно), минуты и часы вычисляются, если нужны.

    сбрасывается на 0 и начинает отсчет с предыдущего состояния

    Что неудивительно - метод run работает с "несброшенными" данными. Чтобы иметь доступ к актуальному состоянию, используйте функциональное обновление.
    Ответ написан
    Комментировать
  • Как реализовать пагинацию GitHub?

    0xD34F
    @0xD34F Куратор тега React
    При поиске надо получить данные пользователя - оттуда достаёте количество репозиториев (свойство public_repos), вычисляете количество страниц.

    Добавляете эффект на изменение настроек пагинации - там выполняете загрузку информации о репозиториях.

    https://codesandbox.io/s/for-httpsqnahabrcomq99469...
    Ответ написан
    2 комментария
  • Как написать одну функцию для 4 разных компонентов?

    0xD34F
    @0xD34F Куратор тега React
    Вместо нескольких стейтов пусть будет один - объект. Общий обработчик onChange достаёт из целевого объекта помимо значения ещё и имя инпута, одновременно являющегося именем обновляемого свойства (его придётся передавать в экземпляры CustomTextField, а внутри самого CustomTextField прокидывать внутрь TextField). Вот так (как добавить два других свойства - думаю, сами догадаетесь):

    interface IFormData {
      firstName: string;
      lastName: string;
    }

    const [ formData, setFormData ] = React.useState<IFormData>({
      firstName: '',
      lastName: '',
    });
    
    const onChange = (e: React.ChangeEvent<HTMLInputElement>) => setFormData({
      ...formData,
      [e.target.name]: e.target.value,
    });

    <CustomTextField name="firstName" value={formData.firstName} onChange={onChange} />
    <CustomTextField name="lastName" value={formData.lastName} onChange={onChange} />
    
    <!-- или -->
    
    {Object.entries(formData).map(([ k, v ]) => (
      <CustomTextField key={k} name={k} value={v} onChange={onChange} />
    ))}
    Ответ написан
    Комментировать
  • Как связать ввод в форму с методом в React?

    0xD34F
    @0xD34F Куратор тега React
    Уберите эффект.

    Функция получения списка репозиториев - пусть получает в качестве параметра имя пользователя:

    async function fetchRepos(username) {
      let result = [];
    
      try {
        result = (await axios.get(`https://api.github.com/users/${username}/repos`)).data;
      } catch(e) {
        console.error(e);
      }
    
      setRepos(result);
    }

    Передавайте её в компонент с формой поиска:

    <Search onSearch={fetchRepos} />

    Внутри которого ей будет передаваться текущее значение из input'а:

    function Search({ onSearch }) {
      const [ searchValue, setSearchValue ] = useState('');
    
      function onSubmit(e) {
        e.preventDefault();
        onSearch(searchValue);
      }
    
      return (
        <form onSubmit={onSubmit}>
          <input
            type="text"
            value={searchValue}
            onChange={e => setSearchValue(e.target.value)}
          />
          <button>Найти</button>
        </form>
      )
    }

    https://jsfiddle.net/2foy6rbw/
    Ответ написан
  • Как изменить цвет текста при выборе option?

    0xD34F
    @0xD34F Куратор тега React
    class App extends React.Component {
      state = {
        colors: [ 'раз цвет', 'два цвет', 'три цвет', 'ещё какой-то цвет', 'и ещё' ],
        selectedColor: '',
      }
    
      onChange = e => {
        this.setState({
          selectedColor: e.target.value,
        });
      }
    
      render() {
        const { colors, selectedColor } = this.state;
    
        return (
          <div>
            <select value={selectedColor} onChange={this.onChange}>
              <option disabled hidden value="">SELECT COLOR</option>
              {colors.map(n => <option>{n}</option>)}
            </select>
    
            {selectedColor &&
              <p style={{ color: selectedColor }}>
                {selectedColor} color selected
              </p>
            }
          </div>
        );
      }
    }
    Ответ написан
    Комментировать
  • Как компоненту Material UI установить id и получить его в обработчике события?

    0xD34F
    @0xD34F Куратор тега React
    onChange={(event) => {
      return test(event, id);
    }}

    И чем же здесь является id? Откуда он берётся? Уж точно не из input'a - этот будет event.target.id.

    onChange={() => {
      return handlerOnChange;
    }}

    Круглые скобки где после handlerOnChange? И зачем постоянно делаете return, что и кому пытаетесь вернуть?

    Короче, id достаёте из target, и не надо никаких дополнительных обёрток над обработчиками событий при их назначении экземплярам TextField:

    const onChange = e => {
      const { id } = e.target;
      ...

    <TextField
      onChange={onChange}
      ...
    Ответ написан
    Комментировать
  • Как добавить два объекта в state?

    0xD34F
    @0xD34F Куратор тега React
    class App extends React.Component {
      state = {
        links: [],
        newLink: {
          href: '',
          text: '',
        },
      }
    
      onChange = ({ target: { name, value } }) => {
        this.setState(({ newLink }) => ({
          newLink: {
            ...newLink,
            [name]: value,
          },
        }));
      }
    
      addLink = e => {
        e.preventDefault();
    
        this.setState(({ links, newLink }) => ({
          links: [ ...links, newLink ],
          newLink: Object.fromEntries(Object.keys(newLink).map(n => [ n, '' ])),
        }));
      }
    
      render() {
        return (
          <div>
            <ul>
              {this.state.links.map(n => (
                <li>
                  <a href={n.href}>{n.text}</a>
                </li>
              ))}
            </ul>
            <form onSubmit={this.addLink}>
              {Object.entries(this.state.newLink).map(([ name, value ]) => (
                <div>
                  {name}:
                  <input name={name} value={value} onChange={this.onChange} />
                </div>
              ))}
              <input type="submit" value="Добавить" />
            </form>
          </div>
        );
      }
    }
    Ответ написан
    Комментировать
  • Как внести данные в модальные окна?

    0xD34F
    @0xD34F Куратор тега React
    карточка и модалка, это как один компонент

    вдруг у меня будет таких карточек не 6 а 106

    А зачем вам шесть окон? Не говоря уже о ста шести. Сделайте одно, которое будет отображать данные любой из карточек:

    function Portfolio() {
      const [ modalData, setModalData ] = useState(null);
      const onClick = (e) => setModalData(cardsData[e.target.dataset.index]);
      const onClose = () => setModalData(null);
    
      return (
        <div>
          {cardsData.map((n, i) => (
            <button data-index={i} onClick={onClick}>
              open modal #{i + 1}
            </button>
          ))}
    
          <Modal isOpen={!!modalData} onRequestClose={onClose}>
            {modalData && (<>
              <h2>{modalData.title}</h2>
              <button onClick={onClose}>close</button>
              <div>{modalData.things}</div>
            </>)}
          </Modal>
          /*
           * или, вместо использования isOpen рендерим окно только в том случае,
           * если есть что в нём показывать
           */
          {modalData && (
            <Modal onRequestClose={onClose}>
              <h2>{modalData.title}</h2>
              <button onClick={onClose}>close</button>
              <div>{modalData.things}</div>
            </Modal>
          )}
        </div>
      );
    }
    Ответ написан
    1 комментарий
  • Почему undefined при выводе из Mobx конкретного объекта?

    0xD34F
    @0xD34F Куратор тега React
    Когда обращаетесь к значению, его ещё нет.

    А изменения не отслеживаются.

    Класс DB - надо добавить дефолтное значение:

    class DB {
      info = null;
      ...

    Компонент Episodes - добавить эффекту значение DB.info в качестве зависимости:

    const Episodes = observer(() => {
      useEffect(() => {
        ...
      }, [ DB.info ]);
      ...

    Если же не хотите видеть дефолтное значение info внутри Episodes, тогда его экземпляр следует рендерить только при наличии данных, в App замените return <Episodes />; на return DB.info && <Episodes />;.
    Ответ написан
    1 комментарий
  • Как сделать что бы при чеке определённый input появлялся и исчезал?

    0xD34F
    @0xD34F Куратор тега React
    Массив выбранных значений у вас есть - вот на его основе и создавайте input'ы:

    <div className={css.inputList}>
      {checkedList.map(n => (
        <div className={css.field} key={n}>
          <p>{n}:</p>
          <Input />
        </div>
      ))}
    </div>
    Ответ написан
    Комментировать
  • Как сгруппировать компоненты по параметру?

    0xD34F
    @0xD34F Куратор тега React
    const grouped = props.mainPage.room.reduce((acc, n) => (
      (acc[n.storey] ??= []).push(n),
      acc
    ), {});

    {Object.entries(grouped).map(([ groupName, group ]) => (
      <div className="group" key={groupName}>
        <h3>{groupName}</h3>
        {group.map(n => <NumberRoom key={n.id} {...n} />)}
      </div>
    ))}
    Ответ написан
  • Как изменить state без костылей?

    0xD34F
    @0xD34F Куратор тега React
    this.setState(({ todos }) => ({
      todos: todos.map((n, i) => i === index
        ? { ...n, isSuccess: true }
        : n
      ),
    }));
    Ответ написан
    Комментировать
  • Почему не выполняется рендеринг после обновления данных?

    0xD34F
    @0xD34F Куратор тега React
    setData(result);

    Значение result здесь всегда одно и то же, а если значение не изменилось - компонент не будет заново отрендерен.
    Можно по-быстрому заставить работать так, как вы хотите, передавая копию объекта: setData({ ...result });.
    Ответ написан
  • Как правильно пройтись по массиву и вернуть нужный jsx элемент?

    0xD34F
    @0xD34F Куратор тега React
    Визуал jsx элемента, как и вопросы форматирования времени и даты не так важны, как важно просто разобраться с возможной последовательностью действий, как все это описать.

    Нечего тут описывать, всё тривиально:

    arr.map(n => {
      const start = форматированное значение n.start_at;
      const end = форматированное значение n.end_at;
    
      return <span>{start} - {end}</span>;
    })
    Ответ написан
    Комментировать
  • Как в Swiper Slider реализовать Lazy Load на React?

    0xD34F
    @0xD34F Куратор тега React
    Надо импортировать модуль Lazy: import { Lazy } from 'swiper';. Этого вы не сделали.

    Подключить его: SwiperCore.use([ Lazy ]);. Этого вы не сделали.

    Экземпляру слайдера указать, что необходима ленивая загрузка: <Swiper lazy={true}>. Этого вы не сделали.

    Изображениям добавить класс swiper-lazy, атрибут src заменить на data-src. Ну, хоть это у вас есть.
    Ответ написан
    1 комментарий
  • Как динамически назначать rowspan ячейкам таблицы?

    0xD34F
    @0xD34F Куратор тега React
    Элементы исходного массива - это данные столбцов. Соответственно, получаете количество строк (максимальная из длин вложенных массивов) и в качестве значения rowspan последним элементам столбцов устанавливаете

    1 + количество_строк - количество_элементов_в_данных_текущего_столбца

    https://jsfiddle.net/th7w51kp/
    Ответ написан
  • Как отловить ошибку передачи пропса?

    0xD34F
    @0xD34F Куратор тега React
    чем это может быть вызвано?

    Тем, что значение isLoadError меняется только с false на true. Надо его как-то обратно сбрасывать.

    Можно следить за значением src, если изменилось, выставлять false:

    useEffect(() => setIsLoadError(false), [ src ]);

    Другой вариант - в ImagePopup пересоздавать экземпляр компонента Image при изменении данных карточки, указав соответствующий ключ:

    <Image key={card ? card.link : 'hello, world!!'}
    Ответ написан
    1 комментарий
  • Как удалять картинку и возвращать при повторном клике React?

    0xD34F
    @0xD34F Куратор тега React
    const [ showImage, setShowImage ] = useState(true);

    <button onClick={() => setShowImage(!showImage)}>click me</button>
    {showImage ? <img src="..." /> : null}
    Ответ написан