首页 > 解决方案 > 访问在另一个函数中分配的值

问题描述

我想从另一个函数中的一个函数访问值。两个函数在同一个范围内,没有嵌套。

我尝试只使用一个函数 ComponentDidMount() 并增加了外部查询的范围,以便可以在内部访问该值。它可以工作,但在控制台中不断出现错误,但显示是正确的。我认为这是因为我对多个事物使用相同的引用。但是如果我缩小范围,同时仍然保持它的一个功能,它就不起作用了。我认为这与创建两个函数而无法访问另一个函数中的值一样。但我不明白,虽然我在第一个函数中设置了值的状态。为什么它会在第二个返回默认值,这是我在构造函数中初始化的?

这就是我现在所拥有的。请注意,ComponentWillMount 可以是任何其他函数。

componentWillMount = () => {
    let query = [];
    this.unsub = this.props.firebase.users().doc(this.props.firebase.userId()).get().then(doc => {
        query.push(doc.data().LinkedUsername)
        const lU = this.props.firebase.users().where("email", "==", query[0])
        lU.get().then(snapshot => {
            // console.log(snapshot.docs[0].id)
            this.setState({queryId: snapshot.docs[0].id});

            console.log(this.state.queryId)

        })
    })
}

componentDidMount = () => {
    this.setState({loading: true});

    console.log(this.state.queryId)

    this.unsubscribe = this.props.firebase
        .users().doc(this.props.firebase.userId()).collection('tasks')
        .onSnapshot(snapshot => {
            let items = [];
            snapshot.forEach(doc =>
                (doc.data().status === false) ?
                    items.push({...doc.data(), uid: doc.id})
                    :
                    null
            );
            this.setState({
                items,
                loading: false,
            });
        });
}

注意控制台位置。第一个控制台返回所需的值,但第二个没有。它返回未定义或我在构造函数中初始化它时分配的内容,如下所示

constructor(props) {
    super(props);
    this.state = {
        loading: false,
        items: [],
        // queryId: null
    };
    this.classes = props;
}

如果我在下面这样做,它会在屏幕上提供所需的输出,但会在控制台中不断抛出相同的错误数千次。

componentDidMount = () => {
    this.setState({loading: true});
    console.log(this.state.queryId)
    let query = [];
    this.unsub = this.props.firebase.users().doc(this.props.firebase.userId()).get().then(doc => {
        query.push(doc.data().LinkedUsername)
        const lU = this.props.firebase.users().where("email", "==", query[0])
        lU.get().then(snapshot => {
            // console.log(snapshot.docs[0].id)
            this.setState({queryId: snapshot.docs[0].id});
            console.log(this.state.queryId)
            this.unsubscribe = this.props.firebase
                .users().doc(this.props.firebase.userId()).collection('tasks')
                .onSnapshot(snapshot => {
                    let items = [];
                    snapshot.forEach(doc =>
                        (doc.data().status === false) ?
                            items.push({...doc.data(), uid: doc.id})
                            :
                            null
                    );
                    this.setState({
                        items,
                        loading: false,
                    });
                });
        })
    })
}

但如果我在下面做,它不会。检查倒数第二行和倒数第三行括号位置的差异。

constructor(props) {
    super(props);
    this.state = {
        loading: false,
        items: [],
        // queryId: null
    };
    this.classes = props;
}

如果我在下面这样做,它会在屏幕上提供所需的输出,但会在控制台中不断抛出相同的错误数千次。

componentDidMount = () => {
    this.setState({loading: true});
    console.log(this.state.queryId)
    let query = [];
    this.unsub = this.props.firebase.users().doc(this.props.firebase.userId()).get().then(doc => {
        query.push(doc.data().LinkedUsername)
        const lU = this.props.firebase.users().where("email", "==", query[0])
        lU.get().then(snapshot => {
            // console.log(snapshot.docs[0].id)
            this.setState({queryId: snapshot.docs[0].id});
            console.log(this.state.queryId)
        })
    })
    this.unsubscribe = this.props.firebase
        .users().doc(this.props.firebase.userId()).collection('tasks')
        .onSnapshot(snapshot => {
            let items = [];
            snapshot.forEach(doc =>
                (doc.data().status === false) ?
                    items.push({...doc.data(), uid: doc.id})
                    :
                    null
            );
            this.setState({
                items,
                loading: false,
            });
        });
}

实际结果

undefined index.js:43
Qz1mFFBgPrUFPfO1YFqVxfVpAbE2 index.js:36 

预期成绩

Qz1mFFBgPrUFPfO1YFqVxfVpAbE2 index.js:43
Qz1mFFBgPrUFPfO1YFqVxfVpAbE2 index.js:36

标签: javascriptreactjs

解决方案


componentDidMount()在初始渲染后被调用。并且setState()是异步调用。

所以基本上,当你的componentWillMount() setState()被调用和状态值被更新时,componentDidMount()已经被调用了。

避免在构造函数中调用或使用 api 或componentWillMount()

您的网络请求应该在componentDidMount()


推荐阅读