Задать вопрос
Ответы пользователя по тегу React
  • Как в react js по нажатию tab установить в нужное место каретку input-а?

    0xD34F
    @0xD34F Куратор тега React
    onKeyDown = e => {
      if (e.key === 'Tab') {
        e.preventDefault();
    
        const
          input = e.target,
          str = input.value,
          currPos = input.selectionStart,
          wordEnd = str.slice(currPos).search(/[^\w]/);
    
        let pos = str.slice(currPos + wordEnd).search(/[^\s]/);
        if (pos) {
          pos += currPos + wordEnd;
        }
        if (pos === currPos) {
          pos = 0;
        }
    
        input.setSelectionRange(pos, pos);
      }
    }

    <input value={this.state.str} onKeyDown={this.onKeyDown} />

    https://jsfiddle.net/acvjhxyt/
    Ответ написан
    Комментировать
  • Почему выдает ошибку "Cannot read property of undefined" при попытке обратиться к свойствам PropTypes?

    0xD34F
    @0xD34F Куратор тега React
    "react": "^16.4.0",

    import React, { Component, PropTypes } from 'react';

    Понятно. Открываем документацию, и видим, что

    Note:
    React.PropTypes has moved into a different package since React v15.5. Please use the prop-types library instead.
    Ответ написан
    2 комментария
  • Как в цикле создавать элементы?

    0xD34F
    @0xD34F Куратор тега React
    Array.from({ length: 5 }, () => <Text>hello, world!!</Text>)
    Ответ написан
    Комментировать
  • Как реализовать через HOC, react?

    0xD34F
    @0xD34F Куратор тега React
    Просто нужно еще чтобы компонент `SortableElement ` принял все пропсы.

    Ну так и передавайте все:

    const SortableItem = SortableElement((props) => (
      <ElementItem {...props} />
    ));
    Ответ написан
    2 комментария
  • Как на React можно реализовать scroll?

    0xD34F
    @0xD34F Куратор тега React
    onScroll = e => {
      if (e.target.offsetHeight + e.target.scrollTop === e.target.scrollHeight) {
        /*
         * здесь предпринимаете действия, имеющие своим результатом
         * демонстрацию дополнительного контента
         */
      }
    }

    <div onScroll={this.onScroll}>
      ...

    https://jsfiddle.net/kszqufd7/
    Ответ написан
    Комментировать
  • Как сгенерировать компоненты на основании данных полученных через ajax?

    0xD34F
    @0xD34F Куратор тега React
    const Image = ({ url }) => (
      <div>
        <img src={url} />
      </div>
    );
    
    class App extends React.Component {
      state = {
        items: [],
      }
    
      componentDidMount() {
        fetch('https://api.kai-zer.ru/dev/method/products.getAll')
          .then(r => r.json())
          .then(r => {
            this.setState({
              items: r.response.items,
            });
          });
      }
    
      render() {
        return (
          <div>
            {this.state.items.map(n => <Image {...n.image} />)}
          </div>
        );
      }
    }
    Ответ написан
    Комментировать
  • Состояние не обновляется, что я упустил?

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

    Да понятно почему - вы при поиске выкидываете объекты раз и навсегда, нечему возвращаться.

    Передавайте исходный массив данных в props, и фильтруйте при поиске его:

    class App extends React.Component {
      state = {
        people: this.props.people,
      };
    
      handeSearch = e => {
        const search = e.target.value.toLowerCase();
    
        this.setState((state, { people }) => ({
          people: people.filter(n => n.name.toLowerCase().includes(search)),
        }));
      }
    
      render() {
        return (
          <div className="contacts">
            <input
              type="text"
              className="search-field"
              onChange={this.handeSearch}
            />
            <ul className="contacts-list">
              {this.state.people.map(n => <Person key={n.id} {...n} />)}
            </ul>
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <App people={Peoples} />,
      document.getElementById('root')
    );
    Ответ написан
    1 комментарий
  • Почему неправильно работает shouldComponentUpdate после использования setState в функции?

    0xD34F
    @0xD34F Куратор тега React
    в shouldComponentUpdate nextState.items почему-то равно всегда this.state.items

    Разумеется - вы же не создаёте новый массив.

    Замените

    let items = this.state.items;
    items.push( undefined );

    на

    let items = [ ...this.state.items, undefined ]
    Ответ написан
    2 комментария
  • Как реализовать динамическое сравнение массивов на основе чекбоксов?

    0xD34F
    @0xD34F Куратор тега React
    Для хранения выбранных значений можно использовать объект, имена свойств которого соответствуют индексам групп чекбоксов, а значения будут массивами значений, соответствующих чекбоксам выбранной группы (вперемешку, без разделения по конкретным чекбоксам). В обработчике клика чекбокса в зависимости от его checked дописываете или выбрасываете значения группы.

    Для вывода значений, выбранных во всех группах берёте массив выбранных значений любой группы, и фильтруете его с условием, что элемент массива присутствует во всех массивах выбранных значений групп.

    Выглядеть это может так, например:

    class App extends React.Component {
      state = {
        selected: {},
        groups: [
          [
            [ 'value_a1', 'value_a2', 'value_a3' ],
            [ 'value_b1', 'value_b2', 'value_b3' ],
            [ 'value_c1', 'value_c2', 'value_c3' ],
          ],
          [
            [ 'value_a1', 'value_b1', 'value_c1' ],
            [ 'value_a2', 'value_b2', 'value_c2' ],
            [ 'value_a3', 'value_b3', 'value_c3' ],
          ],
        ],
      }
    
      onChange = (e, groupIndex, itemIndex) => {
        const selectedGroup = this.state.groups[groupIndex][itemIndex];
        const selectedInfo = this.state.selected[groupIndex] || [];
    
        this.setState({
          selected: {
            ...this.state.selected,
            [groupIndex]: e.target.checked
              ? selectedInfo.concat(selectedGroup)
              : selectedInfo.filter(n => !selectedGroup.includes(n))
          },
        });
      }
    
      render() {
        const { selected, groups } = this.state;
        const matched = (selected[0] || []).filter(n => {
          return groups.every((group, i) => (selected[i] || []).includes(n));
        });
    
        return (
          <div>
            {groups.map((group, groupIndex) => (
              <ul>
                {group.map((item, itemIndex) => (
                  <li>
                    <input
                      type="checkbox"
                      onChange={(e) => this.onChange(e, groupIndex, itemIndex)}
                    />
                    {item.map(val => <span>{val}</span>)}
                  </li>
                ))}
              </ul>
            ))}
            <div>
              {matched.map(val => <span>{val}</span>)}
            </div>
          </div>
        );
      }
    }
    Ответ написан
    1 комментарий
  • В чем ошибка reactJS JSON?

    0xD34F
    @0xD34F Куратор тега React
    Кривой json - проверьте кавычки вокруг ключа во второй строке.
    Компонент Comment - судя по имени и по коду, он должен рендерить один комментарий, а у вас массив. Наверное, тут нужен ещё один компонент - список комментариев.

    const Comment = ({ general, job, address }) => (
      <li>
        <div>first name: {general.firstName}</div>
        <div>last name: {general.lastName}</div>
        <div>company: {job.company}</div>
        <div>address: {address.country}, {address.city}, {address.street}</div>
      </li>
    );
    
    const CommentList = ({ comments }) => (
      <ul>
        {comments.map(n => <Comment {...n} />)}
      </ul>
    );
    
    ReactDOM.render(
      <CommentList comments={comments} />,
      document.getElementById('root')
    );
    Ответ написан
    Комментировать
  • Как реализовать кастомные радиобаттоны на react?

    0xD34F
    @0xD34F Куратор тега React
    Приходит массив объектов, и в объекте надо менять свойство enabled: true
    соответственно в другом объекте это свойство нужно заменить на false.

    А зачем такие сложности?

    Выбрана может быть только одна радиокнопка - вот и храните отдельно индекс/id/... выбранного элемента вместо enabled у каждого.
    Ответ написан
    Комментировать
  • Как при поиске изменить цвет у части слова?

    0xD34F
    @0xD34F Куратор тега React
    .highlighted {
      color: red;
      font-weight: bold;
      font-size: 1.5em;
    }

    class App extends React.Component {
      state = {
        items: [ 'aaa', 'aa1', 'ab1', 'zzz', '00!', 'lorem ipsum dolor...' ],
        search: '',
      }
    
      render() {
        const { items, search } = this.state;
        const regex = RegExp(search, 'g');
        const replacement = '<span class="highlighted">$&</span>';
    
        return (
          <div>
            <input value={search} onChange={e => this.setState({ search: e.target.value })} />
            {search &&
            <ul>
              {items.filter(n => n.includes(search)).map(n =>
                <li dangerouslySetInnerHTML={{ __html: n.replace(regex, replacement) }} />
              )}
            </ul>}
          </div>
        );
      }
    }
    Ответ написан
    1 комментарий
  • Как поменять местами данные у компонентов React?

    0xD34F
    @0xD34F Куратор тега React
    const Input = ({ label, ...props }) => (
      <div>
        <label>
          {label}
          <input {...props} />
        </label>
      </div>
    );
    
    class App extends React.Component {
      state = {
        from: 'Москва',
        to: 'Питер',
      }
    
      onChange = ({ target: { value, name } }) => {
        this.setState(() => ({
          [name]: value,
        }));
      }
    
      swap = () => {
        this.setState(({ from, to }) => ({
          from: to,
          to: from,
        }));
      }
    
      render() {
        return (
          <div>
            <button onClick={this.swap}>swap</button>
            <Input label="откуда" value={this.state.from} name="from" onChange={this.onChange} />
            <Input label="куда" value={this.state.to} name="to" onChange={this.onChange} />
          </div>
        );
      }
    }
    Ответ написан
    1 комментарий
  • Как рендерить разные страницы в ReactJS?

    0xD34F
    @0xD34F Куратор тега React
    this.state = {loadworksheep: false};

    this.setState({loadWorksheep: true});

    Так как правильно - w должна быть большой или маленькой? Вы бы определились.

    const worksheetLoaderPage = (
        WorksheetSelector
    );

    WorksheetSelector ---> <WorksheetSelector />

    Если есть другой способ по нажатию кнопки рендерить другую страницу, то буду крайне рад услышать.

    react router
    Ответ написан
    Комментировать
  • Почему меняется слово во всех сообщениях?

    0xD34F
    @0xD34F Куратор тега React
    Вы берёте значение deleted из элементов массива productsList - естественно, одновременно разных значений быть не может. Надо, чтобы у каждого элемента history был свой deleted:

    toggleRow(index) {
      this.setState(({ productsList, history }) => ({
        productsList: productsList.map((n, i) => i === index
          ? { ...n, deleted: !n.deleted }
          : n
        ),
        history: [
          ...history,
          {
            currentDateInfo: new Date().toLocaleDateString(),
            deleted: !productsList[index].deleted,
            index,
          },
        ],
      }));
    }

    <ul className="list-group">
      {this.state.history.map(n =>
        <li className="list-group-item">
          Row {n.index} {n.deleted ? 'deleted' : 'restored'} at {n.currentDateInfo}
        </li>
      )}
    </ul>
    Ответ написан
  • Как восстановить удаленные данные c таблицы?

    0xD34F
    @0xD34F Куратор тега React
    Как я думал сделать:
    По клику на deleteделать поля Name и Id visibility: none и в стейте сделать переменную isDeleted: true, если true то рендерить кнопку Restor'а, по клику на нее полям возвращать visibility.

    Окей, делаем:

    const ProductItem = ({ product, toggleRow }) => {
      return (
        <tr>
          <th>{product.deleted || product.id}</th>
          <td>{product.deleted || product.name}</td>
          <td>
            <button onClick={toggleRow}>
              {product.deleted ? 'Restore' : 'Delete'}
            </button>
          </td>
        </tr>
      );
    };
    
    class Products extends React.Component {
      state = {
        products: [ 'Apple', 'Peanut', 'Tomato', 'Cucumber', 'Banana', 'Lemon' ].map((n, i) => ({
          id: i + 1,
          name: n,
          deleted: false,
        })),
      }
    
      toggleRow(index) {
        this.setState(({ products }) => ({
          products: products.map((n, i) => i === index
            ? { ...n, deleted: !n.deleted }
            : n
          ),
        }));
      }
    
      render() {
        return (
          <table>
            <thead>
              <tr>
                <th>#</th>
                <th>Product Name</th>
                <th>Delete / Restore</th>
              </tr>
            </thead>
            <tbody>
              {this.state.products.map((n, i) => (
                <ProductItem
                  key={n.id}
                  product={n}
                  toggleRow={() => this.toggleRow(i)}
                />
              ))}
            </tbody>
          </table>
        );
      }
    }

    Правда непонятно, при чём тут удаление? - данные-то на месте остаются, просто не отображаются.
    Ответ написан
    1 комментарий
  • Как отловить id строки и удалить ее?

    0xD34F
    @0xD34F Куратор тега React
    Передавайте в метод удаления индекс удаляемого элемента, например:

    deleteRow={() => this.deleteRow(i)}

    deleteRow(index) {
      const productsList = [...this.state.productsList];
      productsList.splice(index, 1);
      this.setState({
        productsList,
      });
    }
    Ответ написан
  • Как передать аргумент в обработчик?

    0xD34F
    @0xD34F Куратор тега React
    Во-первых, параметр state функции, переданной в setState, перекрывает параметр state, передаваемый в modalRun. Во-вторых, второй параметр функции, передаваемой в setState - это props, а вовсе не state. В общем, дурацким выбором имён параметров сами себя в заблуждение вводите. Делайте так:

    modalRun = (modalState) => {
      this.setState((prevState) => {
        return {
          modal: {
            ...prevState.modal,
            state: modalState,
          },
        };
      });  
    }
    Ответ написан
    2 комментария
  • Почему не работает аутентификация?

    0xD34F
    @0xD34F Куратор тега React
    Забыли return в requireAuth.js, вот здесь:

    connect(mapStateToProps, null)(Authentication);
    Ответ написан
    1 комментарий
  • Как менять disable на enable у кнопки правильно?

    0xD34F
    @0xD34F Куратор тега React
    Описываете кнопки в виде массива, а вместо isDisabled храните индекс неактивной кнопки, как-то так.
    Ответ написан
    Комментировать