{"action":"created","comment":{"url":"https://api.github.com/repos/reactjs/rfcs/pulls/comments/165709737","pull_request_review_id":93697372,"id":165709737,"diff_hunk":"@@ -0,0 +1,400 @@\n+* Start Date: 2017-12-05\n+* RFC PR: (leave this empty)\n+* React Issue: (leave this empty)\n+\n+# Summary\n+\n+Introduce a new version of context that addresses existing limitations.\n+\n+# Basic example\n+\n+```js\n+type Theme = 'light' | 'dark';\n+// Pass a default theme to ensure type correctness\n+const ThemeContext: Context<Theme> = React.createContext('light');\n+\n+class ThemeToggler extends React.Component {\n+  state = {theme: 'light'};\n+  render() {\n+    return (\n+      // Pass the current context value to the Provider's `value` prop.\n+      // Changes are detected using strict comparison (Object.is)\n+      <ThemeContext.Provider value={this.state.theme}>\n+        <button\n+          onClick={() =>\n+            this.setState(state => ({\n+              theme: state.theme === 'light' ? 'dark' : 'light',\n+            }))\n+          }>\n+          Toggle theme\n+        </button>\n+        {this.props.children}\n+      </ThemeContext.Provider>\n+    );\n+  }\n+}\n+\n+class Title extends React.Component {\n+  render() {\n+    return (\n+      // The Consumer uses a render prop API. Avoids conflicts in the\n+      // props namespace.\n+      <ThemeContext.Consumer>\n+        {theme => (\n+          <h1 style={{color: theme === 'light' ? '#000' : '#fff'}}>\n+            {this.props.children}\n+          </h1>\n+        )}\n+      </ThemeContext.Consumer>\n+    );\n+  }\n+}\n+```\n+\n+# Motivation\n+\n+Typically, data in a React application is passed top-down (parent to child) via\n+props. But sometimes it's useful to pass values through multiple levels of\n+abstraction without involving each intermediate. Examples include a locale, or a\n+UI theme. Many components may rely on those but you don't want to have to pass a\n+`locale` prop and a `theme` prop through every level of the tree.\n+\n+Context in React provides a mechanism for a child component to access a value in\n+an ancestor component. In this document, we'll refer to the ancestor as the\n+**provider** and the child as the **consumer**.\n+\n+## Drawbacks of the existing version of context\n+\n+### shouldComponentUpdate blocks context changes\n+\n+The main flaw with context today is how it interacts with\n+`shouldComponentUpdate`. If an intermediate component bails out using\n+`shouldComponentUpdate`, and there are no pending updates further down the tree,\n+React will assume there are no changes and reuse the entire subtree. If the\n+subtree contains a context consumer, the consumer will not receive the latest\n+context. In other words, context changes will not propagate through a component\n+whose `shouldComponentUpdate` return false.\n+\n+`shouldComponentUpdate` is a fairly common optimization in React applications. A\n+shared component or open source library can't assume that applications won't use\n+it. In practice, this means that context alone is not a reliable way to\n+broadcast changes.\n+\n+### Shifts complexity to user space\n+\n+Today, developers circumvent the `shouldComponentUpdate` problem using\n+subscriptions:\n+\n+* The provider acts as an event emitter. It keeps track of the most recent\n+  context value, and a list of subscribers to be notified whenever it changes.\n+* The consumer accesses the provider's event emitter using the context API.\n+  (This usage is fine because the event emitter itself does not change).\n+* The consumer registers an event listener with the provider.\n+* When the provider emits a change event, the consumer is notified and calls\n+  `setState` on itself to schedule a re-render.\n+\n+Subscriptions are widely used by open source libraries such as Redux and React\n+Broadcast. It works, but it has some clear drawbacks:\n+\n+* Not ergonomic. Given how common the context use case is, it shouldn't be so\n+  difficult to implement properly.\n+* Start-up cost. Setting up subscriptions for every consumer is costly,\n+  especially since they aren't used during the initial mount.\n+* Encourages mutation and other non-idiomatic patterns that could cause bugs in\n+  async mode.\n+* The same code ends up being duplicated by every library, increasing bundle\n+  sizes.\n+\n+The meta problem is that the ownership and responsibility for a core feature has\n+been shifted from the framework to its users.\n+\n+## Main goals of this proposal\n+\n+* Zero cost (or close to it) for initial mount, commit, and unmount, trading-off\n+update cost as necessary.\n+* Easy-to-use API.\n+* Statically typable.\n+* Encourage async-friendly practices, like immutability.\n+* Discourage non-ideal practices, like event emitters and mutation.\n+* Eliminate duplicated complexity in userland code.\n+\n+# Detailed design\n+\n+Introduces new component types: `Provider` and `Consumer`.\n+\n+```js\n+type Provider<T> = React.Component<{\n+  value: T,\n+  children?: React.Node,\n+}>;\n+\n+type Consumer<T> = React.Component<{\n+  children: (value: T) => React.Node,\n+}>;\n+```\n+\n+Providers and consumers come in pairs—for each provider, there is a\n+corresponding consumer.\n+\n+A provider-consumer pair is created using `React.createContext()`:\n+\n+```js\n+type Context<T> = {\n+  Provider: Provider<T>,\n+  Consumer: Consumer<T>,\n+};\n+\n+interface React {\n+  createContext<T>(defaultValue: T): Context<T>;\n+}\n+```\n+\n+`createContext` requires a default value to ensure type correctness.\n+\n+Note that an arbitrary provider and arbitrary consumer cannot necessarily be\n+used in conjunction, even if their value type is the same. They must be the\n+result of the same `createContext()` call.\n+\n+The provider accepts a context value as a prop. Any matching consumer in the\n+provider's subtree can access it, regardless of how deeply it's nested.\n+\n+```js\n+render() {\n+  return (\n+    <Provider value={this.state.contextValue}>\n+      {this.props.children}\n+    </Provider>\n+  );\n+}\n+```\n+\n+To update the context value, the parent re-renders and passes a different value.\n+Changes to context are detected using `Object.is` comparison. (Referred to as\n+strict comparision in this proposal, though `Object.is` is different from `===`\n+in some edge cases.) This is meant to encourage the use of immutable or\n+persistent data structures. In the typical scenario, context is updated by\n+calling `setState` on the provider's parent.\n+\n+The consumer uses a render prop API:\n+\n+```js\n+render() {\n+  return (\n+    <Consumer>\n+      {contextValue => <Child arbitraryProp={contextValue} />}\n+    </Consumer>\n+  )\n+}\n+```\n+\n+Notice how in the above example, the context value can be passed to any\n+arbitrary prop on the child component. The advantage of the render prop API is\n+that we avoid clobbering the prop namespace.\n+\n+If a consumer is rendered without a matching provider as its ancestor, it\n+receives the default value passed to `createContext`, ensuring type safety.\n+\n+## Implementation\n+\n+TODO.\n+\n+# Drawbacks\n+\n+## Relies on strict comparison of context values\n+\n+This proposal uses strict (reference) comparison to detect changes to context\n+values. This is partly to encourage the use of immutable or persistent data\n+structures. But many common data sources rely on mutation. For example, certain\n+implementations of Flux, or even newer libraries like Relay Modern.\n+\n+However, there are inherent problems with mutation when combined with async\n+rendering, mostly related to tearing. For architectures that rely on mutation,\n+developers will either decide some level of tearing is acceptable, or evolve to\n+better support async. Regardless, these problems are not exclusive to the\n+context API.\n+\n+An escape hatch for libraries that rely on mutation is to clone the outer\n+container. (Or even just alternate between two copies.) React will detect a new\n+object reference and trigger a change.\n+\n+## Only one provider type per consumer\n+\n+The proposed API only allows for a consumer to read values from a single\n+provider type, unlike the current API, which allows a consumer to read from an\n+arbitrary number of provider types.\n+\n+The solution is to use compose consumers:\n+\n+```js\n+<FooConsumer>\n+  {foo => (\n+    <BarConsumer>\n+      {bar => (\n+        // Render using both foo and bar\n+        <Child foo={foo} bar={bar} />\n+      )}\n+    </BarConsumer>\n+  )}\n+</FooConsumer>;\n+```\n+\n+Most abstractions around context already use similar patterns.\n+\n+# Alternatives\n+\n+## setContext\n+\n+Instead of relying on reference equality to detect changes to context, we could\n+instead use a `setContext` API that works like `setState`. However, setting\n+aside the implementation overhead, this API would only be valuable when combined\n+with mutation, which we're specifically aiming to discourage.\n+\n+## Passing context to shouldComponentUpdate\n+\n+One argument is that we could avoid the `shouldComponentUpdate` problem by\n+passing context as an argument to that method, compare the incoming context to\n+the previous context, and return true if they are different. The problem is\n+that, unlike props or state, we have no type information. The type of the\n+context object depends on the component's position in the React tree. You could\n+perform a shallow comparion of both objects, but that only works if we assume\n+the values are immutable. And if we're going to assume the values are immutable,\n+React might as well do the comparison automatically.\n+\n+## Class-based API\n+\n+Instead of render props, we could use a class-based API similar to the one we\n+have today:\n+\n+```js\n+class ThemeToggler extends React.Component {\n+  state = {theme: 'light'};\n+  getChildContext() {\n+    return this.state.theme;\n+  }\n+  render() {\n+    return (\n+      <>\n+        <button\n+          onClick={() =>\n+            this.setState(state => ({\n+              theme: state.theme === 'light' ? 'dark' : 'light',\n+            }))\n+          }>\n+          Toggle theme\n+        </button>\n+        {this.props.children}\n+      </>\n+    );\n+  }\n+}\n+\n+class Title extends React.Component {\n+  static contextType = ThemeContext;\n+  componentDidUpdate(prevProps, prevState, prevContext) {\n+    if (this.context !== prevContext) {\n+      alert('Theme changed!');\n+    }\n+  }\n+  render() {\n+    return (\n+      <h1 style={{color: this.context.theme === 'light' ? '#000' : '#fff'}}>\n+        {this.props.children}\n+      </h1>\n+    );\n+  }\n+}\n+```\n+\n+The advantage of this API is you'd have easier access to context inside\n+lifecycle methods, possibly avoiding the need for an extra component in the\n+tree.\n+\n+However, although increasing the depth of a React tree incurs some overhead, the\n+advantage of using special component types is that it's faster to scan the tree\n+for consumers, because we can quickly skip over the other types. With the\n+class-based API, we'd have to check every class component, which is slightly\n+slower. This is likely enough to offset the cost of the extra component.\n+\n+Unlike the class API, the render prop API also has the advantage of being\n+sufficiently different from the existing context API that we could support both\n+versions during a transitional period without too much confusion.\n+\n+## Algebraic effects\n+\n+In the past, we've considered modeling context in terms of\n+[algebraic effects](https://github.com/reactjs/react-basic#algebraic-effects).\n+Our conclusion was that memoizing effects (in order to skip over subtrees\n+without reevaluating them) made this approach intractable.\n+\n+# How we teach this\n+\n+This would be our first API that uses render props. They are an increasingly","path":"text/0000-new-version-of-context.md","position":331,"original_position":331,"commit_id":"1e25818e47037a7de80e95793c4129e9887d6f2b","original_commit_id":"1e25818e47037a7de80e95793c4129e9887d6f2b","user":{"login":"FezVrasta","id":5382443,"avatar_url":"https://avatars2.githubusercontent.com/u/5382443?v=4","gravatar_id":"","url":"https://api.github.com/users/FezVrasta","html_url":"https://github.com/FezVrasta","followers_url":"https://api.github.com/users/FezVrasta/followers","following_url":"https://api.github.com/users/FezVrasta/following{/other_user}","gists_url":"https://api.github.com/users/FezVrasta/gists{/gist_id}","starred_url":"https://api.github.com/users/FezVrasta/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FezVrasta/subscriptions","organizations_url":"https://api.github.com/users/FezVrasta/orgs","repos_url":"https://api.github.com/users/FezVrasta/repos","events_url":"https://api.github.com/users/FezVrasta/events{/privacy}","received_events_url":"https://api.github.com/users/FezVrasta/received_events","type":"User","site_admin":false},"body":"Just my 2 cents, if we go with a `render` prop we may as well drop `children` all together, no reason to keep two props that serve the exact same purpose...","created_at":"2018-02-02T17:38:26Z","updated_at":"2018-02-02T17:38:26Z","html_url":"https://github.com/reactjs/rfcs/pull/2#discussion_r165709737","pull_request_url":"https://api.github.com/repos/reactjs/rfcs/pulls/2","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/reactjs/rfcs/pulls/comments/165709737"},"html":{"href":"https://github.com/reactjs/rfcs/pull/2#discussion_r165709737"},"pull_request":{"href":"https://api.github.com/repos/reactjs/rfcs/pulls/2"}},"in_reply_to_id":155365736},"pull_request":{"url":"https://api.github.com/repos/reactjs/rfcs/pulls/2","id":156842854,"html_url":"https://github.com/reactjs/rfcs/pull/2","diff_url":"https://github.com/reactjs/rfcs/pull/2.diff","patch_url":"https://github.com/reactjs/rfcs/pull/2.patch","issue_url":"https://api.github.com/repos/reactjs/rfcs/issues/2","number":2,"state":"closed","locked":false,"title":"New version of context","user":{"login":"acdlite","id":3624098,"avatar_url":"https://avatars0.githubusercontent.com/u/3624098?v=4","gravatar_id":"","url":"https://api.github.com/users/acdlite","html_url":"https://github.com/acdlite","followers_url":"https://api.github.com/users/acdlite/followers","following_url":"https://api.github.com/users/acdlite/following{/other_user}","gists_url":"https://api.github.com/users/acdlite/gists{/gist_id}","starred_url":"https://api.github.com/users/acdlite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acdlite/subscriptions","organizations_url":"https://api.github.com/users/acdlite/orgs","repos_url":"https://api.github.com/users/acdlite/repos","events_url":"https://api.github.com/users/acdlite/events{/privacy}","received_events_url":"https://api.github.com/users/acdlite/received_events","type":"User","site_admin":false},"body":"(supersedes #1)\r\n\r\nA proposal for a new version of context addressing existing limitations.\r\n\r\n[Rendered](https://github.com/acdlite/rfcs/blob/new-version-of-context/text/0000-new-version-of-context.md)\r\n\r\nCorresponding React PR: https://github.com/facebook/react/pull/11818\r\n\r\nTODO:\r\n\r\n- [ ] Implementation notes\r\n- [ ] High-priority version of context, for animations. (May submit this separately.)\r\n- [ ] Add snippet showing how the `displayName` transform would work (https://github.com/reactjs/rfcs/pull/2#discussion_r155430494).\r\n- [ ] Add section about using narrow context types for maximum performance","created_at":"2017-12-06T21:21:51Z","updated_at":"2018-02-02T17:38:26Z","closed_at":"2018-01-25T04:44:31Z","merged_at":"2018-01-25T04:44:31Z","merge_commit_sha":"b091fdb5902234424f402e1a0804e6c937e87afb","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"milestone":null,"commits_url":"https://api.github.com/repos/reactjs/rfcs/pulls/2/commits","review_comments_url":"https://api.github.com/repos/reactjs/rfcs/pulls/2/comments","review_comment_url":"https://api.github.com/repos/reactjs/rfcs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/reactjs/rfcs/issues/2/comments","statuses_url":"https://api.github.com/repos/reactjs/rfcs/statuses/1e25818e47037a7de80e95793c4129e9887d6f2b","head":{"label":"acdlite:new-version-of-context","ref":"new-version-of-context","sha":"1e25818e47037a7de80e95793c4129e9887d6f2b","user":{"login":"acdlite","id":3624098,"avatar_url":"https://avatars0.githubusercontent.com/u/3624098?v=4","gravatar_id":"","url":"https://api.github.com/users/acdlite","html_url":"https://github.com/acdlite","followers_url":"https://api.github.com/users/acdlite/followers","following_url":"https://api.github.com/users/acdlite/following{/other_user}","gists_url":"https://api.github.com/users/acdlite/gists{/gist_id}","starred_url":"https://api.github.com/users/acdlite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acdlite/subscriptions","organizations_url":"https://api.github.com/users/acdlite/orgs","repos_url":"https://api.github.com/users/acdlite/repos","events_url":"https://api.github.com/users/acdlite/events{/privacy}","received_events_url":"https://api.github.com/users/acdlite/received_events","type":"User","site_admin":false},"repo":{"id":113368420,"name":"rfcs","full_name":"acdlite/rfcs","owner":{"login":"acdlite","id":3624098,"avatar_url":"https://avatars0.githubusercontent.com/u/3624098?v=4","gravatar_id":"","url":"https://api.github.com/users/acdlite","html_url":"https://github.com/acdlite","followers_url":"https://api.github.com/users/acdlite/followers","following_url":"https://api.github.com/users/acdlite/following{/other_user}","gists_url":"https://api.github.com/users/acdlite/gists{/gist_id}","starred_url":"https://api.github.com/users/acdlite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acdlite/subscriptions","organizations_url":"https://api.github.com/users/acdlite/orgs","repos_url":"https://api.github.com/users/acdlite/repos","events_url":"https://api.github.com/users/acdlite/events{/privacy}","received_events_url":"https://api.github.com/users/acdlite/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/acdlite/rfcs","description":"RFCs for changes to React","fork":true,"url":"https://api.github.com/repos/acdlite/rfcs","forks_url":"https://api.github.com/repos/acdlite/rfcs/forks","keys_url":"https://api.github.com/repos/acdlite/rfcs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/acdlite/rfcs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/acdlite/rfcs/teams","hooks_url":"https://api.github.com/repos/acdlite/rfcs/hooks","issue_events_url":"https://api.github.com/repos/acdlite/rfcs/issues/events{/number}","events_url":"https://api.github.com/repos/acdlite/rfcs/events","assignees_url":"https://api.github.com/repos/acdlite/rfcs/assignees{/user}","branches_url":"https://api.github.com/repos/acdlite/rfcs/branches{/branch}","tags_url":"https://api.github.com/repos/acdlite/rfcs/tags","blobs_url":"https://api.github.com/repos/acdlite/rfcs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/acdlite/rfcs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/acdlite/rfcs/git/refs{/sha}","trees_url":"https://api.github.com/repos/acdlite/rfcs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/acdlite/rfcs/statuses/{sha}","languages_url":"https://api.github.com/repos/acdlite/rfcs/languages","stargazers_url":"https://api.github.com/repos/acdlite/rfcs/stargazers","contributors_url":"https://api.github.com/repos/acdlite/rfcs/contributors","subscribers_url":"https://api.github.com/repos/acdlite/rfcs/subscribers","subscription_url":"https://api.github.com/repos/acdlite/rfcs/subscription","commits_url":"https://api.github.com/repos/acdlite/rfcs/commits{/sha}","git_commits_url":"https://api.github.com/repos/acdlite/rfcs/git/commits{/sha}","comments_url":"https://api.github.com/repos/acdlite/rfcs/comments{/number}","issue_comment_url":"https://api.github.com/repos/acdlite/rfcs/issues/comments{/number}","contents_url":"https://api.github.com/repos/acdlite/rfcs/contents/{+path}","compare_url":"https://api.github.com/repos/acdlite/rfcs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/acdlite/rfcs/merges","archive_url":"https://api.github.com/repos/acdlite/rfcs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/acdlite/rfcs/downloads","issues_url":"https://api.github.com/repos/acdlite/rfcs/issues{/number}","pulls_url":"https://api.github.com/repos/acdlite/rfcs/pulls{/number}","milestones_url":"https://api.github.com/repos/acdlite/rfcs/milestones{/number}","notifications_url":"https://api.github.com/repos/acdlite/rfcs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/acdlite/rfcs/labels{/name}","releases_url":"https://api.github.com/repos/acdlite/rfcs/releases{/id}","deployments_url":"https://api.github.com/repos/acdlite/rfcs/deployments","created_at":"2017-12-06T21:19:59Z","updated_at":"2018-01-27T15:59:50Z","pushed_at":"2017-12-06T21:20:20Z","git_url":"git://github.com/acdlite/rfcs.git","ssh_url":"git@github.com:acdlite/rfcs.git","clone_url":"https://github.com/acdlite/rfcs.git","svn_url":"https://github.com/acdlite/rfcs","homepage":null,"size":16,"stargazers_count":24,"watchers_count":24,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":4,"open_issues":0,"watchers":24,"default_branch":"master"}},"base":{"label":"reactjs:master","ref":"master","sha":"48b3935f488172e076611b97ac52a75ca04d5256","user":{"login":"reactjs","id":6412038,"avatar_url":"https://avatars3.githubusercontent.com/u/6412038?v=4","gravatar_id":"","url":"https://api.github.com/users/reactjs","html_url":"https://github.com/reactjs","followers_url":"https://api.github.com/users/reactjs/followers","following_url":"https://api.github.com/users/reactjs/following{/other_user}","gists_url":"https://api.github.com/users/reactjs/gists{/gist_id}","starred_url":"https://api.github.com/users/reactjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/reactjs/subscriptions","organizations_url":"https://api.github.com/users/reactjs/orgs","repos_url":"https://api.github.com/users/reactjs/repos","events_url":"https://api.github.com/users/reactjs/events{/privacy}","received_events_url":"https://api.github.com/users/reactjs/received_events","type":"Organization","site_admin":false},"repo":{"id":113273337,"name":"rfcs","full_name":"reactjs/rfcs","owner":{"login":"reactjs","id":6412038,"avatar_url":"https://avatars3.githubusercontent.com/u/6412038?v=4","gravatar_id":"","url":"https://api.github.com/users/reactjs","html_url":"https://github.com/reactjs","followers_url":"https://api.github.com/users/reactjs/followers","following_url":"https://api.github.com/users/reactjs/following{/other_user}","gists_url":"https://api.github.com/users/reactjs/gists{/gist_id}","starred_url":"https://api.github.com/users/reactjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/reactjs/subscriptions","organizations_url":"https://api.github.com/users/reactjs/orgs","repos_url":"https://api.github.com/users/reactjs/repos","events_url":"https://api.github.com/users/reactjs/events{/privacy}","received_events_url":"https://api.github.com/users/reactjs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/reactjs/rfcs","description":"RFCs for changes to React","fork":false,"url":"https://api.github.com/repos/reactjs/rfcs","forks_url":"https://api.github.com/repos/reactjs/rfcs/forks","keys_url":"https://api.github.com/repos/reactjs/rfcs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/reactjs/rfcs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/reactjs/rfcs/teams","hooks_url":"https://api.github.com/repos/reactjs/rfcs/hooks","issue_events_url":"https://api.github.com/repos/reactjs/rfcs/issues/events{/number}","events_url":"https://api.github.com/repos/reactjs/rfcs/events","assignees_url":"https://api.github.com/repos/reactjs/rfcs/assignees{/user}","branches_url":"https://api.github.com/repos/reactjs/rfcs/branches{/branch}","tags_url":"https://api.github.com/repos/reactjs/rfcs/tags","blobs_url":"https://api.github.com/repos/reactjs/rfcs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/reactjs/rfcs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/reactjs/rfcs/git/refs{/sha}","trees_url":"https://api.github.com/repos/reactjs/rfcs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/reactjs/rfcs/statuses/{sha}","languages_url":"https://api.github.com/repos/reactjs/rfcs/languages","stargazers_url":"https://api.github.com/repos/reactjs/rfcs/stargazers","contributors_url":"https://api.github.com/repos/reactjs/rfcs/contributors","subscribers_url":"https://api.github.com/repos/reactjs/rfcs/subscribers","subscription_url":"https://api.github.com/repos/reactjs/rfcs/subscription","commits_url":"https://api.github.com/repos/reactjs/rfcs/commits{/sha}","git_commits_url":"https://api.github.com/repos/reactjs/rfcs/git/commits{/sha}","comments_url":"https://api.github.com/repos/reactjs/rfcs/comments{/number}","issue_comment_url":"https://api.github.com/repos/reactjs/rfcs/issues/comments{/number}","contents_url":"https://api.github.com/repos/reactjs/rfcs/contents/{+path}","compare_url":"https://api.github.com/repos/reactjs/rfcs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/reactjs/rfcs/merges","archive_url":"https://api.github.com/repos/reactjs/rfcs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/reactjs/rfcs/downloads","issues_url":"https://api.github.com/repos/reactjs/rfcs/issues{/number}","pulls_url":"https://api.github.com/repos/reactjs/rfcs/pulls{/number}","milestones_url":"https://api.github.com/repos/reactjs/rfcs/milestones{/number}","notifications_url":"https://api.github.com/repos/reactjs/rfcs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/reactjs/rfcs/labels{/name}","releases_url":"https://api.github.com/repos/reactjs/rfcs/releases{/id}","deployments_url":"https://api.github.com/repos/reactjs/rfcs/deployments","created_at":"2017-12-06T05:32:51Z","updated_at":"2018-02-02T12:03:56Z","pushed_at":"2018-01-30T14:23:42Z","git_url":"git://github.com/reactjs/rfcs.git","ssh_url":"git@github.com:reactjs/rfcs.git","clone_url":"https://github.com/reactjs/rfcs.git","svn_url":"https://github.com/reactjs/rfcs","homepage":null,"size":57,"stargazers_count":809,"watchers_count":809,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":40,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":40,"open_issues":10,"watchers":809,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/reactjs/rfcs/pulls/2"},"html":{"href":"https://github.com/reactjs/rfcs/pull/2"},"issue":{"href":"https://api.github.com/repos/reactjs/rfcs/issues/2"},"comments":{"href":"https://api.github.com/repos/reactjs/rfcs/issues/2/comments"},"review_comments":{"href":"https://api.github.com/repos/reactjs/rfcs/pulls/2/comments"},"review_comment":{"href":"https://api.github.com/repos/reactjs/rfcs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/reactjs/rfcs/pulls/2/commits"},"statuses":{"href":"https://api.github.com/repos/reactjs/rfcs/statuses/1e25818e47037a7de80e95793c4129e9887d6f2b"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"FezVrasta"}}