Всегда ли дочерние компоненты React должны быть с сохранением состояния?

javascript #reactjs

#javascript #reactjs

Вопрос:

Когда единственной целью дочернего компонента является использование состояния его родительского компонента, должен ли он сам быть с сохранением состояния?

Рассмотрим эти два примера:

«Без состояния»

 const ServicesCard = ({ service, onClick, isPro = false }) => {
  const name = isPro amp;amp; service.pro?._id ? service.pro.pro_name : service.name;
  let price = isPro amp;amp; service.pro?._id ? service.pro.total : service.total;

  // Special case scenarios
  let prefix;
  let suffix;

  if (service.hasPages) {
    prefix = 'from';
  }
  if (service.uid === 'abcdef') {
    prefix = '';
    price = `${price} per page`;
    suffix = '($5 minimum)';
  }
  if (service.uid === 'qwerty') {
    suffix = "  gov't fees";
  }

  return (
    <div className={styles.servicesCard} onClick={onClick}>
      <h1 className={styles.header}>{name}</h1>
      <p className={styles.pricing}>
        <span className={styles.prefix}>{prefix}</span>
        <span className={styles.price}>{`${price}`}</span>
        <span className={styles.suffix}>{suffix}</span>
      </p>
    </div>
  );
};
 

С отслеживанием состояния

 const ServicesCard = ({ service, onClick, isPro = false }) => {
  const [name, setName] = useState('');
  const [price, setPrice] = useState('');
  const [prefix, setPrefix] = useState('');
  const [suffix, setSuffix] = useState('');

  useEffect(() => {
    const _name = isPro amp;amp; service.pro?._id ? service.pro.pro_name : service.name;
    let _price = isPro amp;amp; service.pro?._id ? service.pro.total : service.total;

    // Special case scenarios
    let _prefix;
    let _suffix;

    if (service.hasPages) {
      _prefix = 'from';
    }
    if (service.uid === 'abcdef') {
      _prefix = '';
      _price = `${_price} per page`;
      _suffix = '($5 minimum)';
    }
    if (service.uid === 'qwerty') {
      _suffix = "  gov't fees";
    }

    setName(_name)
    setPrice(_price)
    setPrefix(_prefix)
    setSuffix(_suffix)
  }, [service]);

  return (
    <div className={styles.servicesCard} onClick={onClick}>
      <h1 className={styles.header}>{name}</h1>
      <p className={styles.pricing}>
        <span className={styles.prefix}>{prefix}</span>
        <span className={styles.price}>{`${price}`}</span>
        <span className={styles.suffix}>{suffix}</span>
      </p>
    </div>
  );
};
 

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

При условии, что service это единственная поддержка, которая меняется, почему я должен использовать больше памяти браузера с помощью API useState amp; useEffect React?

Комментарии:

1. Нет, компоненты без состояния в порядке. Ранее общим правилом было сделать как можно большую часть вашей кодовой базы без состояния.

2. Ваш JSX не обновляет состояние во втором примере, он просто использует onClick переданный в него обработчик, поэтому использование state в этом компоненте довольно бессмысленно.

3. В дополнение к комментарию @Andy’s, в React фактически считается антишаблоном сохранять переданные реквизиты в состояние локального компонента, просто используйте реквизиты непосредственно в дочерних компонентах. Чтобы ответить на базовый вопрос «Всегда ли дочерние компоненты React должны быть с сохранением состояния?» — ну, нет, им нужно состояние только тогда, когда им нужно состояние, т. Е. Когда для них имеет смысл «владеть» некоторым состоянием локально.