无法在 componentWillMount 中设置状态
Can't set state in componentWillMount
我正在创建一个简单的聊天应用程序,我通过 axios returns 消息对象数组对我的数据库进行 api 调用。当我在 componentWillMount 中进行 axios 调用时,我能够获取数据。然后我试图 setState 来显示对话。这是代码:
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 ]
})
})
};
我看过一些关于生命周期函数和设置状态的帖子,看来我做的是对的。
再次强调,axios 调用工作正常,设置状态无效。我仍然看到一个空数组。提前致谢!
编辑:这是专门针对我的问题的解决方案。它被埋在评论中,所以我想我会把它留在这里..
"I discovered the issue. It was actually in how I was parsing my data. The spread operator on ...messages.content didn't work because messages.content doesn't exist. messages[i].content exists. So my fix was to spread just ...messages Then in a child component I map over the objects and parse the .content property. Thanks for the help guys!"
componentWillMount() is invoked immediately before mounting occurs. It
is called before render(), therefore setting state in this method will
not trigger a re-rendering. Avoid introducing any side-effects or
subscriptions in this method. docs
因此,您需要调用 componentDidMount
作为-
componentDidMount() {
axios.get(`api/messages`)
.then((result) => {
const messages = result.data
console.log("COMPONENT WILL Mount messages : ", messages);
this.setState({
messages: [ ...messages.content ]
})
})
在你的情况下,你的 setState()
将不起作用,因为你在异步回调中使用 setState()
工作Fiddle:https://jsfiddle.net/xytma20g/3/
您正在进行 API 异步调用。所以,setState
只会在收到数据后调用。它不会对 componentWillMount
或 componentDidMount
做任何事情。您需要处理渲染中的空 message
。当您从 API 收到数据时,将该数据设置为状态,组件将使用新状态重新渲染,这将反映在您的渲染中。
伪代码:
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.
}
};
我正在创建一个简单的聊天应用程序,我通过 axios returns 消息对象数组对我的数据库进行 api 调用。当我在 componentWillMount 中进行 axios 调用时,我能够获取数据。然后我试图 setState 来显示对话。这是代码:
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 ]
})
})
};
我看过一些关于生命周期函数和设置状态的帖子,看来我做的是对的。
再次强调,axios 调用工作正常,设置状态无效。我仍然看到一个空数组。提前致谢!
编辑:这是专门针对我的问题的解决方案。它被埋在评论中,所以我想我会把它留在这里..
"I discovered the issue. It was actually in how I was parsing my data. The spread operator on ...messages.content didn't work because messages.content doesn't exist. messages[i].content exists. So my fix was to spread just ...messages Then in a child component I map over the objects and parse the .content property. Thanks for the help guys!"
componentWillMount() is invoked immediately before mounting occurs. It is called before render(), therefore setting state in this method will not trigger a re-rendering. Avoid introducing any side-effects or subscriptions in this method. docs
因此,您需要调用 componentDidMount
作为-
componentDidMount() {
axios.get(`api/messages`)
.then((result) => {
const messages = result.data
console.log("COMPONENT WILL Mount messages : ", messages);
this.setState({
messages: [ ...messages.content ]
})
})
在你的情况下,你的 setState()
将不起作用,因为你在异步回调中使用 setState()
工作Fiddle:https://jsfiddle.net/xytma20g/3/
您正在进行 API 异步调用。所以,setState
只会在收到数据后调用。它不会对 componentWillMount
或 componentDidMount
做任何事情。您需要处理渲染中的空 message
。当您从 API 收到数据时,将该数据设置为状态,组件将使用新状态重新渲染,这将反映在您的渲染中。
伪代码:
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.
}
};