Почему в версии кода React ловится ошибка макс. Стека вызовов, а в версии класса - нет? - PullRequest
0 голосов
/ 13 апреля 2020

Я написал компонент класса, который, казалось, работал нормально и не сталкивался ни с какими ошибками. Затем я попытался переключить его на использование Hooks, потому что позже я хотел воспользоваться useContext. Однако теперь, в версии моего кода Hooks, я сталкиваюсь с ошибкой максимального количества вызовов в стеке и не знаю, как ее исправить.

Вот оригинальная версия компонента класса, которая работала:

constructor(props: Props) {
    super(props);
    this.state = {
      currentItemIndex: 0,
      carouselFocused: false,
    };
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
  componentDidUpdate(prevProps: Props, prevState: State) {
    if (prevState.carouselFocused !== this.state.carouselFocused) {
      if (this.state.carouselFocused === true) {
        this.subscription = leftEventEmitter$.subscribe(value => {
          this.setState((state, props) => ({
            currentItemIndex: loop(state.currentItemIndex - 1, 0, props.data.length - 1),
          }));
        });
        this.subscription.add(
          rightEventEmitter$.subscribe(value =>
            this.setState((state, props) => ({
              currentItemIndex: loop(state.currentItemIndex + 1, 0, props.data.length - 1),
            }))
          )
        );
      }
    }
    if (this.subscription) {
      if (!this.state.carouselFocused) {
        this.subscription.unsubscribe();
      }
    }
  }
  static getDerivedStateFromProps(props: Props, state: State) {
    if (props.focused !== state.carouselFocused) {
      return {
        carouselFocused: props.focused,
      };
    }
    return null;
  }
  private subscription?: Subscription;
  componentWillUnmount() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }

Вот версия Hooks, которая приводит к ошибке максимального стека вызовов:

const [currentItemIndex, setCurrentItemIndex] = useState(0);
const [carouselFocused, setCarouselFocused] = useState(false);
let subscription: Subscription;

  useEffect(() => {
    if (props.focused !== carouselFocused) {
      setCarouselFocused(props.focused);
    }
  });
  useEffect(() => {
    if (carouselFocused === true) {
      subscription = leftEventEmitter$.subscribe(value => {
        setCurrentItemIndex(prevState => loop(prevState - 1, 0, props.data.length - 1));
      });
      subscription.add(
        rightEventEmitter$.subscribe(value => {
          setCurrentItemIndex(prevState => loop(prevState + 1, 0, props.data.length - 1));
        })
      );
    }
    return () => {
      if (subscription) {
        subscription.unsubscribe();
      }
    };
  }, [carouselFocused]);

Ошибка показывает l oop код:

export function loop(value: number, min: number, max: number): number {
  const range = max - min + 1;
  if (value < min) {
    return loop(value + range, min, max);
  } else if (value > max) {
    return loop(value - range, min, max);
  } else {
    return value;
  }
}

Как исправить ошибку максимального стека вызовов?

1 Ответ

0 голосов
/ 13 апреля 2020

Когда вы звоните

setCurrentItemIndex(prevState => loop(prevState - 1, 0, props.data.length - 1));

с исходным значением currentItemIndex = 0 и props.data.length = 0

Затем вы будете вызывать l oop (- 1, 0 , -1) это go превратится в бесконечное l oop, потому что диапазон будет равен 0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...