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>
    );
}