Why is my React component is rendering twice?

淺唱寂寞╮ 提交于 2020-05-21 05:30:26

问题


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;

回答1:


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

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.

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


来源:https://stackoverflow.com/questions/48846289/why-is-my-react-component-is-rendering-twice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!