Пропустить изменение хука (useEffect) при инициализации - PullRequest
0 голосов
/ 06 января 2020

Я создал компонент функции с раскрывающимся списком. Каждый раз, когда пользователь выбирает новое значение, я отправляю событие потребляющему компоненту. Я использую крючки для выбранного индекса. Я понял, что крючки работают asyn c. Когда было выбрано новое значение, старое значение было проведено для компонента потребления. Поэтому я начал использовать «useEffect». Однако useEffect имеет тот побочный эффект, который вызывается при инициализации переменной. Можно ли как-то сказать REACT не отправлять событие useEffect при инициализации, чтобы я не отправлял выбранное событие изменения при инициализации? Вы просто добавляете логическую переменную (например, hasBeenInit) или есть что-то умнее?

https://codesandbox.io/s/blissful-clarke-ky1nr?fontsize=14&hidenavigation=1&theme=dark

import React, { useState, useEffect } from "react";
import {
  Dropdown,
  DropdownToggle,
  DropdownMenu,
  DropdownItem,
  Button
} from "reactstrap";

const DropdownPaging = props => {
  const [selectedValue, setSelectedValue] = useState(10);
  const [dropdownOpen, setDropdownOpen] = useState(false);
  const [pageIndex, setPageIndex] = useState(0);

  const toggle = () => setDropdownOpen(prevState => !prevState);

  function dropDownChanged(val) {
    setSelectedValue(val);
  }

  useEffect(() => {
    triggerEventChange(selectedValue, pageIndex);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedValue, pageIndex]);

  function pageIndexIncremented() {
    setPageIndex(counter => counter + 1);
  }

  function pageIndexDecremented() {
    if (pageIndex >= 1) {
      setPageIndex(counter => counter - 1);
    } else {
      setPageIndex(0);
    }
  }

  function triggerEventChange(take, index) {
    if (props.valueChanged) {
      props.valueChanged({ take: take, pageIndex: index });
    } else {
    }
  }

  return (
    <div>
      <table>
        <tr>
          <td>
            <Button
              outline
              disabled={pageIndex === 0}
              color="dark"
              onClick={pageIndexDecremented}
            >
              &lt;
            </Button>
          </td>
          <td>{pageIndex}</td>
          <td>
            <Button outline color="dark" onClick={pageIndexIncremented}>
              &gt;
            </Button>
          </td>
          <td>
            <Dropdown isOpen={dropdownOpen} toggle={toggle}>
              <DropdownToggle caret outline color="dark">
                {selectedValue}
              </DropdownToggle>
              <DropdownMenu>
                <DropdownItem onClick={() => dropDownChanged(10)}>
                  10
                </DropdownItem>
                <DropdownItem onClick={() => dropDownChanged(25)}>
                  25
                </DropdownItem>
                <DropdownItem onClick={() => dropDownChanged(50)}>
                  50
                </DropdownItem>
                <DropdownItem onClick={() => dropDownChanged(100)}>
                  100
                </DropdownItem>
              </DropdownMenu>
            </Dropdown>
          </td>
        </tr>
      </table>
    </div>
  );
};

export default DropdownPaging;

Ответы [ 2 ]

1 голос
/ 06 января 2020

Вы можете использовать useRef, чтобы смоделировать, смонтирован ли компонент или нет, поэтому ваш компонент становится:

  const mounted = useRef(false);
  const toggle = () => setDropdownOpen(prevState => !prevState);

  function dropDownChanged(val) {
    setSelectedValue(val);
  }

  useEffect(() => {
    if (mounted.current) {
      triggerEventChange(selectedValue, pageIndex);
    } else {
      mounted.current = true;
    }

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedValue, pageIndex]);

Обновленная песочница: https://codesandbox.io/s/dropdownpager-urvrp

0 голосов
/ 06 января 2020

Логическое значение является опцией. Если вам нужно поведение в других местах вашего приложения, вы можете создать пользовательский хук:

const useEffectIgnoringInit = (callBack, watchedValues) => {
  const [hasBeenInit, setHasBeenInit] = useState(true);
  useEffect(() => {
    if(hasBeenInit){
      callBack();
    } else {
      setHasBeenInit(true);
    }
  }, watchedValues);
}

Тогда вы используете его вместо useEffect:

useEffectIgnoringInit(() => {
  triggerEventChange(selectedValue, pageIndex);
  // eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedValue, pageIndex]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...