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! "
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.
}
};
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 ]
})
})