Home > Net >  setState() in componentDidMount() - When is the intermediate state REALLY noticeable TO THE USER?
setState() in componentDidMount() - When is the intermediate state REALLY noticeable TO THE USER?

Time:09-13

The React doc states that the intermediate state will not be shown to the user, but why in this example it does show "loading...." (the intermediate state in this case)?

You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state.

class MyComponent extends React.Component {
        constructor(props) {
            
          super(props);
          this.state = {
            error: null,
            isLoaded: false,
            items: []
          };
        }
    
        componentDidMount() {
    
          fetch("https://jsonplaceholder.typicode.com/posts")
            .then(res => res.json())
            .then(
              (result) => {
                this.setState({
                  isLoaded: true,
                  items: result
                });
              },
              // Note: it's important to handle errors here
              // instead of a catch() block so that we don't swallow
              // exceptions from actual bugs in components.
              (error) => {
                this.setState({
                  isLoaded: true,
                  error
                });
              }
            )
        }
        render() {
    
          const { error, isLoaded, items } = this.state;
          if (error) {
    
            return <div>Error: {error.message}</div>;
          } else if (!isLoaded) {
    
            return <div>Loading...</div>;
          } else {
    
            return (
              <ul>
                {items.map(item => (
                  <li key={item.id}>
                    {item.userId} - {item.title}
                  </li>
                ))}
              </ul>
            );
          }
        }
    }

When I do not use AJAX calls the intermediate state is not seen ("loading...) for example:

class MyComponent extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            error: null,
            isLoaded: false,
            items: []
          };
        }
        componentDidMount() {
                                  
          this.setState({
            isLoaded: true,
            items: [
              { "id": 1, "name": "Apples",  "price": "$2" },
              { "id": 2, "name": "Peaches", "price": "$5" }
            ] 
          });
              
        }
        render() {
          const { error, isLoaded, items } = this.state;
          if (error) {
            return <div>Error: {error.message}</div>;
          } else if (!isLoaded) {
            return <div>Loading...</div>;
          } else {
            return (
              <ul>
                {items.map(item => (
                  <li key={item.id}>
                    {item.id} - {item.name}
                  </li>
                ))}
              </ul>
            );
          }
        }
      }

CodePudding user response:

Because in the first example, you're not calling setState immediately in componentDidMount().

You're calling it from a function the asynchronous fetch() invocation (eventually) calls.

  • Related