setState() 的异步性质不显示来自父组件的更新道具
Async nature of setState() not showing updated props from parent component
我知道 setState()
在设计上是异步的,我明白为什么 - 因为 JS 是单线程的,浏览器也是如此,因此重新渲染是一项昂贵的操作。我有一个非常(似乎是)简单的问题。
我正在从 Firebase 接收一些数据,我正在使用 setState()
将该数据设置为组件状态,因此我可以将其作为 props 发送给 About.js
组件。正在发生的事情是引擎正在跳过 setState()
(自然地),因为它是异步的,并将道具注入 About.js
组件。 About.js
组件中的 props 为 null,因为它正在从初始设置为 null 的父组件接收初始 props。
我尝试了整个回调方法,但我被这个小怪癖困住了(我希望他们在以后添加一个操作来为 setState()
在同步和异步之间进行选择)。
无论如何,这是代码--- 非常简单。在此先感谢您的帮助!
App.js
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
home_skills: null
}
this.sendSkillProps = this.sendSkillProps.bind(this);
}
sendSkillProps(delta) {
return (previousState, currentProps) => {
return {...previousState, home_skills: delta}
}
}
componentDidMount() {
// GET LIST HOME SKILLSET FROM FIREBASE
const db = firebase.firestore();
var skillset_ref = db.collection('SOME_COLLEC_ID').doc('SOME_DOC_ID');
skillset_ref.onSnapshot((doc) => {
if (doc.exists) {
this.setState(this.sendSkillProps(doc.data()));
}
else {
console.log("No such document!");
}
});
}
render() {
return (
<div className="App">
<Navbar />
<MainSplash />
<About madskills={this.state.home_skills} />
</div>
);
}} export default App;
About.js
export default class About extends React.Component {
constructor (props) {
super(props);
this.state = {}
}
componentDidMount() {
console.log(this.props.madskills); // LOGS AS NULL
}
render() {
return (
...
据我所知,setState 的异步性质与此无关。你似乎有过于复杂的事情。这应该有效:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
home_skills: null
}
}
componentDidMount() {
// GET LIST HOME SKILLSET FROM FIREBASE
const db = firebase.firestore();
var skillset_ref = db.collection('SOME_COLLEC_ID').doc('SOME_DOC_ID');
skillset_ref.onSnapshot((doc) => {
if (doc.exists) {
this.setState({home_skills: doc.data()});
}
else {
console.log("No such document!");
}
});
}
render() {
return (
<div className="App">
<Navbar />
<MainSplash />
<About madskills={this.state.home_skills} />
</div>
);
}} export default App;
在 App.js 文件
的 componentDidMount() 中试试这个
componentDidMount() {
// GET LIST HOME SKILLSET FROM FIREBASE
const db = firebase.firestore();
var skillset_ref = db.collection('SOME_COLLEC_ID').doc('SOME_DOC_ID');
skillset_ref.onSnapshot( async (doc) => {
if (doc.exists) {
await this.setState(this.sendSkillProps(doc.data()));
}
else {
console.log("No such document!");
}
});
}
感谢@hussain.codes,这成功了(也感谢其他所有人!):
render() {
return (
<div className="App">
<Navbar />
<MainSplash />
{
this.state.home_skills != null ? <About madskills={this.state.home_skills} /> : <h1>Loading...</h1>
}
</div>
);
}
我知道 setState()
在设计上是异步的,我明白为什么 - 因为 JS 是单线程的,浏览器也是如此,因此重新渲染是一项昂贵的操作。我有一个非常(似乎是)简单的问题。
我正在从 Firebase 接收一些数据,我正在使用 setState()
将该数据设置为组件状态,因此我可以将其作为 props 发送给 About.js
组件。正在发生的事情是引擎正在跳过 setState()
(自然地),因为它是异步的,并将道具注入 About.js
组件。 About.js
组件中的 props 为 null,因为它正在从初始设置为 null 的父组件接收初始 props。
我尝试了整个回调方法,但我被这个小怪癖困住了(我希望他们在以后添加一个操作来为 setState()
在同步和异步之间进行选择)。
无论如何,这是代码--- 非常简单。在此先感谢您的帮助!
App.js
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
home_skills: null
}
this.sendSkillProps = this.sendSkillProps.bind(this);
}
sendSkillProps(delta) {
return (previousState, currentProps) => {
return {...previousState, home_skills: delta}
}
}
componentDidMount() {
// GET LIST HOME SKILLSET FROM FIREBASE
const db = firebase.firestore();
var skillset_ref = db.collection('SOME_COLLEC_ID').doc('SOME_DOC_ID');
skillset_ref.onSnapshot((doc) => {
if (doc.exists) {
this.setState(this.sendSkillProps(doc.data()));
}
else {
console.log("No such document!");
}
});
}
render() {
return (
<div className="App">
<Navbar />
<MainSplash />
<About madskills={this.state.home_skills} />
</div>
);
}} export default App;
About.js
export default class About extends React.Component {
constructor (props) {
super(props);
this.state = {}
}
componentDidMount() {
console.log(this.props.madskills); // LOGS AS NULL
}
render() {
return (
...
据我所知,setState 的异步性质与此无关。你似乎有过于复杂的事情。这应该有效:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
home_skills: null
}
}
componentDidMount() {
// GET LIST HOME SKILLSET FROM FIREBASE
const db = firebase.firestore();
var skillset_ref = db.collection('SOME_COLLEC_ID').doc('SOME_DOC_ID');
skillset_ref.onSnapshot((doc) => {
if (doc.exists) {
this.setState({home_skills: doc.data()});
}
else {
console.log("No such document!");
}
});
}
render() {
return (
<div className="App">
<Navbar />
<MainSplash />
<About madskills={this.state.home_skills} />
</div>
);
}} export default App;
在 App.js 文件
的 componentDidMount() 中试试这个componentDidMount() {
// GET LIST HOME SKILLSET FROM FIREBASE
const db = firebase.firestore();
var skillset_ref = db.collection('SOME_COLLEC_ID').doc('SOME_DOC_ID');
skillset_ref.onSnapshot( async (doc) => {
if (doc.exists) {
await this.setState(this.sendSkillProps(doc.data()));
}
else {
console.log("No such document!");
}
});
}
感谢@hussain.codes,这成功了(也感谢其他所有人!):
render() {
return (
<div className="App">
<Navbar />
<MainSplash />
{
this.state.home_skills != null ? <About madskills={this.state.home_skills} /> : <h1>Loading...</h1>
}
</div>
);
}