componentDidMount-Äquivalent für eine React-Funktion / Hooks-Komponente?

99

Gibt es Möglichkeiten, componentDidMountin React Funktionskomponenten über Hooks zu simulieren ?

Jeyko
quelle

Antworten:

199

Für die stabile Version von Hooks (React Version 16.8.0+)

Zum componentDidMount

useEffect(() => {
  // Your code here
}, []);

Zum componentDidUpdate

useEffect(() => {
  // Your code here
}, [yourDependency]);

Zum componentWillUnmount

useEffect(() => {
  // componentWillUnmount
  return () => {
     // Your code here
  }
}, [yourDependency]);

In dieser Situation müssen Sie Ihre Abhängigkeit an dieses Array übergeben. Nehmen wir an, Sie haben einen solchen Zustand

const [count, setCount] = useState(0);

Und wenn die Anzahl steigt, möchten Sie Ihre Funktionskomponente neu rendern. Dann useEffectsolltest du so aussehen

useEffect(() => {
  // <div>{count}</div>
}, [count]);

Auf diese Weise wird Ihre Komponente bei jeder Aktualisierung Ihrer Anzahl neu gerendert. Hoffentlich hilft das ein bisschen.

Mertcan Diken
quelle
Gründliche Erklärung! Gibt es eine Möglichkeit, componentDidReceiveProps zu simulieren?
Jeyko
1
Ich bin mir dessen nicht bewusst, auch wenn es existiert. Sie können diesen Thread überprüfen, bis github.com/facebook/react/issues/3279
Mertcan Diken
1
Vielen Dank dafür, da mir das zweite Argument in nicht bekannt war useState. undefinedWenn Sie dies lesen, denken Sie bitte daran, dass das Verlassen des zweiten Arguments dazu führt, dass Ihr Effekt bei jedem Rendern ausgelöst wird (wenn ich mich nicht irre).
Dimiguel
Meinen Sie Abhängigkeiten von useEffect (Übergeben eines Abhängigkeitsarrays)? Wenn ja, wenn Sie es leer lassen, ist das ein Fehler im Code. Für die Array-Dekonstruktion benötigen Sie beide [count, setCount], da count in diesem Beispiel Ihre Statusvariable ist und setCount Ihre Funktion zum Aktualisieren dieses Status ist.
Mertcan Diken
Danke für die Antwort. Die Dokumentation dazu finden Sie hier reactjs.org/docs/hooks-effect.html
Josh
3

Obwohl die akzeptierte Antwort funktioniert, wird sie nicht empfohlen. Wenn Sie mehr als einen Status haben und ihn mit useEffect verwenden, werden Sie gewarnt, ob Sie ihn dem Abhängigkeitsarray hinzufügen oder überhaupt nicht verwenden.

Es verursacht manchmal das Problem, das zu unvorhersehbaren Ausgaben führen kann. Ich schlage daher vor, dass Sie sich ein wenig Mühe geben, um Ihre Funktion als Klasse neu zu schreiben. Es gibt nur sehr wenige Änderungen, und Sie können einige Komponenten als Klasse und einige als Funktion haben. Sie sind nicht verpflichtet, nur eine Konvention zu verwenden.

Nehmen Sie das zum Beispiel

function App() {
  const [appointments, setAppointments] = useState([]);
  const [aptId, setAptId] = useState(1);

  useEffect(() => {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = aptId;
          console.log(aptId);
          setAptId(aptId + 1);
          return item;
        })
        setAppointments(apts);
      });
  }, []);

  return(...);
}

und

class App extends Component {
  constructor() {
    super();
    this.state = {
      appointments: [],
      aptId: 1,
    }
  }

  componentDidMount() {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = this.state.aptId;
          this.setState({aptId: this.state.aptId + 1});
          console.log(this.state.aptId);
          return item;
        });
        this.setState({appointments: apts});
      });
  }

  render(...);
}

Dies ist nur zum Beispiel . Lassen Sie uns daher nicht über Best Practices oder potenzielle Probleme mit dem Code sprechen. Beide haben dieselbe Logik, aber die spätere funktioniert nur wie erwartet. Möglicherweise erhalten Sie die componentDidMount-Funktionalität, wenn useEffect für diese Zeit ausgeführt wird. Wenn Ihre App jedoch wächst, besteht die Möglichkeit, dass Sie auf einige Probleme stoßen. Anstatt in dieser Phase neu zu schreiben, ist es besser, dies in einem frühen Stadium zu tun.

Außerdem ist OOP nicht so schlecht, wenn prozedurorientierte Programmierung genug wäre, hätten wir niemals objektorientierte Programmierung gehabt. Es ist manchmal schmerzhaft, aber besser (technisch. Persönliche Probleme beiseite).

Aniket Kariya
quelle
1
Ich tat dies. Ich hatte Probleme mit Haken. Das Problem war behoben, nachdem es in eine Klasse konvertiert wurde.
Julez
2

Es gibt keine componentDidMountfunktionalen Komponenten, aber React Hooks bieten eine Möglichkeit, das Verhalten mithilfe des Hooks zu emulieren useEffect.

Übergeben Sie ein leeres Array als zweites Argument useEffect(), um nur den Rückruf nur beim Mounten auszuführen.

Bitte lesen Sie die Dokumentation amuseEffect .

function ComponentDidMount() {
  const [count, setCount] = React.useState(0);
  React.useEffect(() => {
    console.log('componentDidMount');
  }, []);

  return (
    <div>
      <p>componentDidMount: {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

ReactDOM.render(
  <div>
    <ComponentDidMount />
  </div>,
  document.querySelector("#app")
);
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

Yangshun Tay
quelle
0

Sie möchten verwenden useEffect(), was je nach Verwendung der Funktion genau wie componentDidMount () funktionieren kann.

Z.B. Sie können eine benutzerdefinierte loadedStatuseigenschaft verwenden, die anfänglich auf false festgelegt ist, und beim Rendern auf true umschalten und den Effekt nur dann auslösen, wenn sich dieser Wert ändert.

Dokumentation

Markmoxx
quelle
1
Diese Lösung ist nicht ideal. Es ist eine schlechte Idee, einen Statuswert zu verwenden, um festzustellen, ob eine Komponente bereitgestellt wurde. Wenn Sie eine Eigenschaft verwenden würden, wäre eine Referenz besser, da sie kein erneutes Rendern auslösen würde.
Yangshun Tay
0

Der genaue äquivalente Hook für componentDidMount () ist

useEffect(()=>{},[]);

hoffe das ist hilfreich :)

Aravinth
quelle