为什么我的React组件渲染两次? [英] Why is my React component is rendering twice?

查看:158
本文介绍了为什么我的React组件渲染两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道为什么我的React组件渲染两次.因此,我从参数中提取了一个电话号码并将其保存为状态,以便可以在Firestore中进行搜索.除了渲染两次外,其他所有东西似乎都工作正常……第一个渲染电话号码和零分.第二次渲染所有数据时,显示正确.有人可以引导我找到解决方案.

I don't know why my React component is rendering twice. So I am pulling a phone number from params and saving it to state so I can search through Firestore. Everything seems to be working fine except it renders twice... The first one renders the phone number and zero points. The second time it renders all the data is displayed correctly. Can someone guide me to the solution.

class Update extends Component {
constructor(props) {
    super(props);
    const { match } = this.props;
    this.state = {
        phoneNumber: match.params.phoneNumber,
        points: 0,
        error: ''
    }
}

getPoints = () => {
    firebase.auth().onAuthStateChanged((user) => {
        if(user) {
            const docRef = database.collection('users').doc(user.uid).collection('customers').doc(this.state.phoneNumber);
            docRef.get().then((doc) => {
                if (doc.exists) {
                const points = doc.data().points;
                this.setState(() => ({ points }));
                console.log(points);
                } else {
                // doc.data() will be undefined in this case
                console.log("No such document!");
                const error = 'This phone number is not registered yet...'
                this.setState(() => ({ error }));
                }
                }).catch(function(error) {
                console.log("Error getting document:", error);
                });
        } else {
            history.push('/')
        }
    });
}

componentDidMount() {
    if(this.state.phoneNumber) {
        this.getPoints();
    } else {
        return null;
    }
}

render() {
    return (
        <div>
            <div>
                <p>{this.state.phoneNumber} has {this.state.points} points...</p>
                <p>Would you like to redeem or add points?</p>
            </div>
            <div>
                <button>Redeem Points</button>
                <button>Add Points</button>
            </div>
        </div>
    );
  }
}

export default Update;

推荐答案

React在getPoints完成异步操作之前渲染组件.

React is rendering the component before getPoints finishing the asynchronous operation.

因此第一个render显示points的初始状态,即0,然后调用componentDidMount并触发异步操作.
完成异步操作并更新状态后,将使用新数据触发另一个render.

So the first render shows the initial state for points which is 0, then componentDidMount is called and triggers the async operation.
When the async operation is done and the state been updated, another render is triggered with the new data.

如果需要,可以显示加载程序或指示符,以指示正在获取数据并且尚未准备好通过条件渲染.

If you want, you can show a loader or an indicator that the data is being fetched and is not ready yet to display with conditional rendering.

只需添加另一个布尔型键(如isFetching),则在调用服务器时将其设置为true,而在接收到数据时将其设置为false.

Just add another Boolean key like isFetching, set it to true when you call the server and set it to false when the data is received.

您的渲染器可能看起来像这样:

Your render can look something like this:

  render() {
    const { isFetching } = this.state;
    return (
      <div>
        {isFetching ? (
          <div>Loading...</div>
        ) : (
          <div>
            <p>
              {this.state.phoneNumber} has {this.state.points} points...
            </p>
            <p>Would you like to redeem or add points?</p>
            <div>
              <button>Redeem Points</button>
              <button>Add Points</button>
            </div>
          </div>
        )}
      </div>
    );
  }

这篇关于为什么我的React组件渲染两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆