Как использовать shouldComponentUpdate с React Hooks? - PullRequest
0 голосов
/ 24 мая 2019

Я читал эти ссылки:
https://reactjs.org/docs/hooks-faq.html#how-do-i-implement-shouldcomponentupdate
https://reactjs.org/blog/2018/10/23/react-v-16-6.html

В первой ссылке написано (https://reactjs.org/docs/hooks-faq.html#from-classes-to-hooks):

shouldComponentUpdate: См. React.memo

Вторая ссылка также гласит, что:

Компоненты класса могут выручить от рендеринга, когда их входные реквизиты одинаковы с использованием PureComponent или shouldComponentUpdateТеперь вы можете сделать то же самое с компонентами функций, поместив их в React.memo.


Что необходимо:

Я хочу, чтобы модал отображался только тогда, когда модал видим (управляемыйby this.props.show)

Для компонента класса:

shouldComponentUpdate(nextProps, nextState) {
    return nextProps.show !== this.props.show;
}

Как использовать вместо memo функциональный компонент - здесь, в Modal.jsx?


Связанный код:

Функциональный компонент Modal.jsx (я не знаю, как проверить props.show)



import React, { useEffect } from 'react';
import styles from './Modal.module.css';
import BackDrop from '../BackDrop/BackDrop';

const Modal = React.memo(props => {
  useEffect(() => console.log('it did update'));

  return (
    <React.Fragment>
      <BackDrop show={props.show} clicked={props.modalClosed} />
      <div
        className={styles.Modal}
        style={{
          transform: props.show ? 'translateY(0)' : 'translateY(-100vh)',
          opacity: props.show ? '1' : '0'
        }}>
        {props.children}
      </div>
    </React.Fragment>
  );
});

export default Modal;

Часть компонента класса PizzaMaker jsxчто делает модал:



 return (
      <React.Fragment>
        <Modal show={this.state.purchasing} modalClosed={this.purchaseCancel}>
          <OrderSummary
            ingredients={this.state.ingredients}
            purchaseCancelled={this.purchaseCancel}
            purchaseContinued={this.purchaseContinue}
            price={this.state.totalPrice}
          />
        </Modal>
        ...
      </React.Fragment>
    );

Ответы [ 2 ]

3 голосов
/ 24 мая 2019

Вот документация для React.memo

. Вы можете передать функцию для управления сравнением:

const Modal = React.memo(
  props => {...},
  (prevProps, nextProps) => prevProps.show === nextProps.show
);

, когда функция возвращает true,компонент не будет перерисован

0 голосов
/ 24 мая 2019

Давайте предположим, что у вас есть функциональный компонент с состоянием с именем CountDown, он получает prop с именем value и уменьшает это значение до тех пор, пока не достигнет 0. Теперь, чтобы сделать это с использованием системы реактивности React, вы должны сериализоватьэтот реквизит в состоянии CountDown и меняйте его, пока он не достигнет 0. Давайте напишем такой компонент:

const CountDown = ({value}) =>{
    const [current, setter] = useState(value)

    if(current > 0)
        setter(current-1)


    return( 
        <div>{current}</div>
    )
}

Заметили проблему?Сериализовав ваше value в состояние CountDown, мы просто потеряли возможность рендеринга всякий раз, когда меняется этот реквизит.Если value никогда не изменяется, то проблем нет, но если это так, вам нужно убедиться, что ваш компонент CountDown также рендерится.Для этого мы можем использовать хук useEffect.

useEffect(() =>{
    setter(value)
}, [value])

Передав массив зависимостей в качестве второго аргумента, мы сообщаем React выполнять обновление данного компонента только тогда, когда одно из значений передается какизменения зависимостей.

...