wake-up-neo.net

Status kann nicht in ComponentWillMount gesetzt werden

Ich erstelle eine einfache Chat-App, in der ich über axios einen API-Aufruf an meine Datenbank mache, der ein Array von Nachrichtenobjekten zurückgibt. Ich kann die Daten abrufen, wenn ich in ComponentWillMount einen Axios-Aufruf mache. Dann versuche ich, den Status so einzustellen, dass die Konversation angezeigt wird. Hier ist der Code:

export default class Chat extends Component {
  constructor(props){
    super(props);

    this.state = {
      messages : [],
      message : '',
    };
    this.socket = io('/api/');
    this.onSubmitMessage = this.onSubmitMessage.bind(this);
    this.onInputChange = this.onInputChange.bind(this);
  }

  componentWillMount() {
    axios.get(`api/messages`)
      .then((result) => {
        const messages = result.data
        console.log("COMPONENT WILL Mount messages : ", messages);
        this.setState({ 
          messages: [ ...messages.content ] 
        })
  })
};

Ich habe einige Beiträge zu Lebenszyklusfunktionen und zum Einstellungsstatus gesehen, und es scheint, als würde ich das Richtige tun. 

Um es noch einmal hervorzuheben, funktionieren Axios einwandfrei. Das Einstellen des Status funktioniert nicht. Ich sehe immer noch ein leeres Array. Danke im Voraus!

EDIT: Hier ist die Lösung speziell für mein Problem. Es wurde in einem Kommentar begraben, also dachte ich, ich würde es hier lassen ..

"Ich habe das Problem entdeckt. Eigentlich habe ich meine Daten analysiert. Der Spread-Operator für ... messages.content hat nicht funktioniert, weil messages.content nicht existiert. Messages [i] .content existiert Fix war nur zu verbreiten ... messages Dann habe ich in einer Kindkomponente die Objekte überlagert und die .content-Eigenschaft analysiert. Danke für die Hilfe, Jungs! "

10
Phil

In Ihrem Fall funktioniert Ihre setState() nicht, da Sie setState() in einem asynchronen Rückruf verwenden.

Arbeitsgeige: https://jsfiddle.net/xytma20g/3/

Sie machen einen API-Aufruf, der asynchron ist. Die Variable setState wird also erst nach dem Empfang der Daten aufgerufen. Es macht nichts mit componentWillMount oder componentDidMount. Sie müssen die leere message in Ihrem Rendering behandeln. Wenn Sie Ihre Daten von der API erhalten, setzen Sie diese Daten auf den Status und die Komponente wird mit dem neuen Status erneut gerendert, der in Ihrem Rendering angezeigt wird. 

Pseudo-Code:

export default class Chat extends Component {
  constructor(props){
    super(props);

    this.state = {
      messages : [],
      message : '',
    };
    this.socket = io('/api/');
    this.onSubmitMessage = this.onSubmitMessage.bind(this);
    this.onInputChange = this.onInputChange.bind(this);
  }

  componentWillMount() {
    axios.get(`api/messages`)
      .then((result) => {
        const messages = result.data
        console.log("COMPONENT WILL Mount messages : ", messages);
        this.setState({ 
          messages: [ ...messages.content ] 
        })
  })

  render(){
    if(this.state.messages.length === 0){
     return false //return false or a <Loader/> when you don't have anything in your message[]
    }

   //rest of your render.
  }
}; 
11
Pranesh Ravi

componentWillMount () wird unmittelbar vor dem Mounten aufgerufen. Es wird vor render () aufgerufen, daher wird das Setzen des Status in dieser Methode kein Re-Rendering auslösen. Vermeiden Sie das Einführen von Nebenwirkungen oder Abonnements in dieser Methode. docs

Sie müssen also componentDidMount als

componentDidMount() {
    axios.get(`api/messages`)
      .then((result) => {
        const messages = result.data
        console.log("COMPONENT WILL Mount messages : ", messages);
        this.setState({ 
          messages: [ ...messages.content ] 
        })
  })
0
Fazal Rasel