aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/vendor/react-router/docs/api/mixins/AsyncState.md
blob: e3a40c8ce0edfc5457fb5df2a0af086c58a36747 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
API: `AsyncState` (mixin)
=========================

A mixin for route handlers that fetch at least part of their state
asynchronously.

Static Lifecycle Methods
------------------------

### `getInitialAsyncState(params, query, setState)`

Fetches state for a component after it mounts. Much like the familiar
`getInitialState` method, `getInitialAsyncState` should return a hash of
key/value pairs to use in the component's state.  The difference is that
the values may be promises. As these values resolve, the component's
state is updated.

#### Parameters

##### params (object)

The url parameters.

##### query (object)

The url query parameters

##### setState (function)

A function that can be used to `setState` as it is received, useful for
things like `xhr` progress and streamed data. Typically you won't use
this.

Props
-----

### `initialAsyncState`

When testing, use the `initialAsyncState` prop to simulate asynchronous
data fetching. When this prop is present, no attempt is made to retrieve
additional state via `getInitialAsyncState`.

Examples
--------

In it simplest form, just return a hash of promises, they become state:

```js
var User = React.createClass({
  mixins: [ Router.AsyncState ],
 
  statics: {
    getInitialAsyncState: function (params, query, setState) {
      return {
        user: fetchUser(params.userId),
        activity: fetchActivityForUser(params.userId)
      }
    }
  },

  render: function() {
    return this.state.user ?
      <LoadingUserProfile/> :
      <UserProfile user={this.state.user} activity={this.state.activity} />;
  }
});
```

But you can get fancier...

```js
var User = React.createClass({
  mixins: [ Router.AsyncState ],
 
  statics: {
    getInitialAsyncState: function (params, query, setState) {
      var buffer = '';

      return {
        user: getUserByID(params.userID) // may be a promise
        activity: {}, // an immediate value (not a promise)
        stream: getStreamingData(params.userID, function (chunk) {
          // `getStreamingData` returns a promise, but also calls back as
          // data is received, giving us a chance to update the UI with
          // progress using the `AsyncState` specific `setState`
          // function
          buffer += chunk;
          setState({ streamBuffer: buffer });
        })
      };
    }
  },
 
  getInitialState: function () {
    return {
      user: null,        // Receives a value when getUserByID resolves.
      stream: null,      // Receives a value when getStreamingData resolves.
      streamBuffer: ''   // Used to track data as it loads.
    };
  },
 
  render: function () {
    if (!this.state.user)
      return <LoadingUser/>;
 
    return (
      <div>
        <p>Welcome {this.state.user.name}!</p>
        <p>So far, you've received {this.state.streamBuffer.length} data!</p>
      </div>
    );
  }
});
```