Ich bin neu bei React. Ich versuche, diesem Beispiel mit der tickenden Uhr zu folgen, mache aber etwas anderes. Ich möchte, dass das ReactDOM im index.js gerendert wird. Hier ist mein Code:

Timer.js:

import React from 'react';

const Timer = () => {
    const tick = () => {
        return new Date().toLocaleTimeString().toString();
    };

    const element = (
        <div>
            <h1>Hello World!</h1>
            <h2>It is {tick()} !</h2>
        </div>
    );

    return (
        element
    );
};

export default Timer;

App.js:

/*jshint esversion: 8 */
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Timer from './Timer'

function App() {
  return (
    <div className="App">
      <Timer />
    </div>
  );
}

export default App;

index.js:

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import * as serviceWorker from "./serviceWorker";
import App from './App';

setInterval(ReactDOM.render(<App />, document.getElementById("root")), 1000);

serviceWorker.unregister();

Es wird jedoch nur die aktuelle Uhrzeit auf dem Bildschirm gedruckt und nicht angekreuzt. Warum funktioniert der Code setInterval(ReactDOM.render(<App />, document.getElementById("root")), 1000); auf index.js nicht?

1
thinkvantagedu 19 Feb. 2020 im 19:49

3 Antworten

Beste Antwort

Es wird empfohlen, das direkte Aufrufen der Renderfunktion zu vermeiden. Sie können Ihr Timer zu einer Komponente machen und es mit Statusänderungen aktualisieren lassen. So würde es mit seinem Lebenszyklus reagieren. Beispielsweise:

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      time: new Date().toLocaleTimeString().toString()
    };
  }
  tick() {
    this.setState({
      time: new Date().toLocaleTimeString().toString()
    });
  }
  componentDidMount() {
    this.intervalID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.intervalID);
  }
  render() {
    return (
      <div>
            <h1>Hello World!</h1>
            <h2>It is {this.state.time} !</h2>
        </div>
    );
  }
} 

export default Timer;

Beachten Sie, dass ich zwei der React Cycle-Funktionen componentDidMount und componentWillUnmount verwendet habe, um die Komponente nach Abschluss des Moutings erneut zu aktualisieren, und die andere, um die Intervallvariable zu löschen, sobald die Reaktion die Bereitstellung Ihrer Komponente aufgehoben hat.

3
Thiago 19 Feb. 2020 im 17:21

Setzen Sie das Datumsfeld auf das Statusobjekt und setzen Sie in der Tick-Funktion setInterval, um mit setState einen neuen Status auf Status zu setzen. Verwenden Sie den Wert state.date, um die Uhrzeit anzuzeigen. React rendert jedes Mal einen neuen Dom, wenn der Status mit der Funktion setState geändert wird.

Ein funktionierendes Beispiel für einen Timer wurde in Reaktionsdokumenten angegeben. Wenn Sie ihn lesen, können Sie viel helfen. https://reactjs.org/docs/state-and-lifecycle.html

1
Renji Joseph Sabu Niravath 19 Feb. 2020 im 17:08

Sie können React.useEffect als zweites Argument verwenden, indem Sie ein Array übergeben, was componentDidMount entspricht.

Sie möchten dann setInterval verwenden, um den Status jede Sekunde festzulegen.

Geben Sie eine Funktion von useEffect zurück, um das Intervall zu löschen, in dem die Bereitstellung der Komponente aufgehoben wird.

Siehe Arbeitscodesandbox hier.

Ihr Code würde wie folgt aussehen:

const function Timer() {
  const [time, setTime] = React.useState(null);
  React.useEffect(() => {
    const tick = () => {
      return new Date().toLocaleTimeString().toString();
    };
    const intervalId = setInterval(() => {
      setTime(tick());
      return () => clearInterval(intervalId);
    }, 1000);
  }, []);

  return <h2>It is {time} !</h2>;
}
2
Paul Fitzgerald 19 Feb. 2020 im 17:18