componentWillReceiveProps, componentDidUpdate для React Hook

Почему бы не использовать command.getoutput () вместо?

import commands

text = "Mario Balotelli" 
output = 'espeak "%s"' % text
print text
a = commands.getoutput(output)
2
задан Deng Zhebin 23 February 2019 в 16:43
поделиться

2 ответа

В вашем сценарии вам вообще не нужно использовать или повторно внедрять getDerivedStateFromProps. Вам просто нужно создать новую переменную, чтобы получить новую форму данных. Использование состояния в этом сценарии вызовет еще один повторный рендеринг, который не является хорошим с точки зрения производительности.

import React from 'react';

const App = ({ count }) => {
  const derivedCount = count > 100 ? 100 : count;

  return (
    <div>Counter: {derivedCount}</div>
  );
}

App.propTypes = {
  count: PropTypes.number.isRequired
}

Демонстрация здесь: https://codesandbox.io/embed/qzn8y9y24j?fontsize=14

Подробнее о различных способах решения подобных сценариев можно прочитать без используя getDerivedStateFromProps здесь: https://reactjs.org/blog/2018/06/07/you-probbly-dont-need-derived-state.html

Если вы действительно нужно использовать отдельное состояние, вы можете использовать что-то подобное

import React, { useState } from 'react';

const App = ({ count }) => {
  const [derivedCounter, setDerivedCounter] = useState(
    count > 100 ? 100 : count
  );

  useEffect(() => {
    setDerivedCounter(count > 100 ? 100 : count);
  }, [count]); // this line will tell react only trigger if count was changed

  return <div>Counter: {derivedCounter}</div>;
};
0
ответ дан Kevin F. 23 February 2019 в 16:43
поделиться

Я понимаю, что ваш пример «производного состояния» преднамеренно прост, но поскольку существует очень мало законных случаев производного состояния, трудно дать рекомендацию о замене, кроме как в каждом конкретном случае, поскольку он зависит от причина, по которой вы используете производное состояние. В приведенном вами конкретном примере не было никакой причины использовать производное состояние в случае класса, и поэтому в случае ловушки по-прежнему нет никаких причин (значение может быть просто получено локально, не переводя его в состояние). Если полученное значение дорого, вы можете использовать useMemo, как представляет Tholle. Если они не соответствуют более реалистичным случаям, которые вы имеете в виду, вам нужно представить более конкретный случай, который действительно требует производного состояния.

Насколько ваш пример componentDidUpdate, если то, что вы хотите сделать для разных реквизитов, является независимым, то вы можете использовать отдельные эффекты для каждого (то есть, несколько useEffect вызовов). Если вы хотите сделать точно , как в вашем примере (т.е. сделать что-то только для изменения companyName, если groupName также не изменилось, как указано вашим else if), тогда вы можете использовать ссылки для более сложных условий. Вы не должны не изменять мутировку ref во время рендеринга (всегда существует вероятность того, что рендер будет отброшен / переделан, если поддерживается параллельный режим), поэтому в примере используется последний эффект для обновления ссылок. В моем примере я использую ссылку, чтобы не выполнять эффектную работу на начальном рендере (см. Ответ Толле в на этот связанный вопрос ) и чтобы определить, изменился ли groupName при принятии решения о том, выполнять работу или нет. на основе изменения companyName.

const { useState, useEffect, useRef } = React;

const DerivedStateFromProps = ({ count }) => {
  const derivedCount = count > 100 ? 100 : count;

  return (
    <div>
      Derived from {count}: {derivedCount}{" "}
    </div>
  );
};
const ComponentDidUpdate = ({ groupName, companyName }) => {
  const initialRender = useRef(true);
  const lastGroupName = useRef(groupName);
  useEffect(
    () => {
      if (!initialRender.current) {
        console.log("Do something when groupName changes", groupName);
      }
    },
    [groupName]
  );
  useEffect(
    () => {
      if (!initialRender.current) {
        console.log("Do something when companyName changes", companyName);
      }
    },
    [companyName]
  );
  useEffect(
    () => {
      if (!initialRender.current && groupName === lastGroupName.current)
        console.log(
          "Do something when companyName changes only if groupName didn't also change",
          companyName
        );
    },
    [companyName]
  );
  useEffect(
    () => {
      // This effect is last so that these refs can be read accurately in all the other effects.
      initialRender.current = false;
      lastGroupName.current = groupName;
    },
    [groupName]
  );

  return null;
};
function App() {
  const [count, setCount] = useState(98);
  const [groupName, setGroupName] = useState("initial groupName");
  const [companyName, setCompanyName] = useState("initial companyName");
  return (
    <div>
      <div>
        <DerivedStateFromProps count={count} />
        <button onClick={() => setCount(prevCount => prevCount + 1)}>
          Increment Count
        </button>
      </div>
      <div>
        <ComponentDidUpdate groupName={groupName} companyName={companyName} />
        groupName:{" "}
        <input
          type="text"
          value={groupName}
          onChange={event => setGroupName(event.target.value)}
        />
        <br />
        companyName:{" "}
        <input
          type="text"
          value={companyName}
          onChange={event => setCompanyName(event.target.value)}
        />
        <br />
        change both{" "}
        <input
          type="text"
          onChange={event => {
            const suffix = event.target.value;
            setGroupName(prev => prev + suffix);
            setCompanyName(prev => prev + suffix);
          }}
        />
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<div id="root"></div>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

Edit Derived state and componentDidUpdate

0
ответ дан Ryan Cogswell 23 February 2019 в 16:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: