{"action":"created","comment":{"url":"https://api.github.com/repos/reactjs/reactjs.org/pulls/comments/193218530","pull_request_review_id":126148524,"id":193218530,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5MzIxODUzMA==","diff_hunk":"@@ -0,0 +1,331 @@\n+---\n+title: \"When to Use Derived State?\"\n+author: [bvaughn]\n+---\n+\n+React 16.4 included a [bugfix for getDerivedStateFromProps](/blog/2018/05/23/react-v-16-4.html#bugfix-for-getderivedstatefromprops) that caused some pain in the React community. We apologize for this. We take such changes very seriously. In this case we believe it was the right decision, but we could have done a better job with communication.\n+\n+[`getDerivedStateFromProps`](/docs/react-component.html#static-getderivedstatefromprops) was introduced in 16.3. At the time, we provided [some examples](/blog/2018/03/27/update-on-async-rendering.html#examples) of how to use the new lifecycle to derive state from props. Our primary goal was to help people migrate from legacy lifecycles to newer ones that are safer to use with the [upcoming async rendering mode](blog/2018/03/01/sneak-peek-beyond-react-16.html).\n+\n+Since that blog post was written, we've observed some common usage patterns for both the legacy `componentWillReceiveProps` and the newer `getDerivedStateFromProps` that cause bugs or otherwise confusing behavior. The 16.4 bugfix [makes this behavior more predictable](https://github.com/facebook/react/issues/12898), but the fixes aren't always obvious. Hopefully this blog post will help!\n+\n+Let's take a look at the following topics:\n+* [When should I use derived state?](#when-should-i-use-derived-state)\n+* [When should I avoid derived state?](#when-should-i-avoid-derived-state)\n+* [What about memoization?](#what-about-memoization)\n+\n+## When should I use derived state?\n+\n+`getDerivedStateFromProps` exists for only one purpose. It enables a component to update its internal state as the result of **changes in external props**. This distinction is important. The problems we've seen so far can be ultimately reduced to either (1) unconditionally updating state from props or (2) updating state whenever props and state don't match. (We'll go over both in more detail below.)\n+\n+So what does it mean to update state as the result of changes in props? Our previous blog post provided a few examples, like [managing the current scroll direction based on an offset prop](/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props) or [loading external data specified by a source prop](/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data-when-props-change).\n+\n+As a general rule, if you're not sure about whether you should use `getDerivedStateFromProps`, here are some questions to ask yourself:\n+* Is the state **derived** from props (as opposed to just mirroring it)?\n+* Is the state update specifically triggered by a **props change** (and not just the current props value)?\n+\n+If your answer to either of the above questions is \"no\" then there are better patterns to use.\n+\n+## When should I avoid derived state?\n+\n+The terms [\"controlled\"](/docs/forms.html#controlled-components) and [\"uncontrolled\"](/docs/uncontrolled-components.html) are often used to refer to form components, but they can also be used to describe where a component's state lives. A piece of behavior that is passed in as props can be thought of as **controlled** and one that exists only in internal state can be thought of as **uncontrolled**.\n+\n+The most common mistake with derived state is mixing these two. In other words, when props control a value in state that is also updated by `setState` calls. This may sound similar to the [external data loading example](/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data-when-props-change) mentioned above, but it's different in a few important ways.\n+\n+In the loading example, there is a clear source of truth for both the \"source\" prop and the \"loading\" state. When the source prop changes, the loading state should **always** be overridden. Conversely the state should only be overridden when the prop **changes** and should otherwise be managed by the component.\n+\n+Problems arise when any of these constraints are changed. This typically comes in two forms. Let's take a look at both.\n+\n+### Anti-pattern: Props always override state\n+\n+A common misconception about both `getDerivedStateFromProps` and `componentWillReceiveProps` is that they are only called when props \"change\". However, any time a parent component re-renders, the child component still receives the new props. Because of this, it is (and has always been) unsafe to _unconditionally_ override state values using either of these lifecycles.\n+\n+Before React 16.4, it was difficult to reproduce such bugs consistently because they depend on the timing of parent re-rendering. To expose them consistently, we made `getDerivedStateFromProps` in React 16.4 fire for renders caused by `setState` or `forceUpdate` too. Let’s consider an example to demonstrate the problem.\n+\n+Here is a `EmailInput` component that accepts an email prop:\n+```js\n+class EmailInput extends Component {\n+  state = {\n+    email: this.props.email\n+  };\n+\n+  static getDerivedStateFromProps(props, state) {\n+    // This is bad! Do not do this!\n+    if (props.email) {\n+      return { email: props.email };\n+    }\n+    return null;\n+  }\n+\n+  render() {\n+    return <input onChange={this.handleChange} value={this.state.email} />;\n+  }\n+\n+  handleChange = event => {\n+    this.setState({ email: event.target.value });\n+  };\n+}\n+```\n+\n+At first, this component might look okay. State is initialized to the value specified by props and updated when we type into the `<input>`. But once our component re-renders– either because it called `setState` or because its parent re-rendered– anything we've typed into the `<input>` will be lost! (See [this demo for an example](codesandbox://when-to-use-derived-state/derived-state-anti-pattern).)\n+\n+At this point, you might be wondering if this component would have worked with version 16.3. Unfortunately, the answer is \"no\". Before moving on, let's take a look at why this is.\n+\n+For the simple example above, we could \"fix\" the problem of unexpected re-renders using `shouldComponentUpdate`. However in practice, components usually accept multiple props, and our component would re-render if any one of them changed. Even if none of them \"changed\", props that are functions or objects are often created inline and so will always bypass `shouldComponentUpdate`. For example, what if our component accepted a function to validate the current email address?\n+```js\n+<EmailInput\n+  email={this.props.user.email}\n+  validate={this.validateEmail.bind(this)}\n+/>\n+```\n+\n+The above example binds the validation callback inline and so it will pass a new function prop every time it renders– effectively bypassing `shouldComponentUpdate` entirely. [Here is a demo](codesandbox://when-to-use-derived-state/derived-state-anti-pattern) that uses a timer to illustrate this problem. Because it might break at any time your component needs to accept new props, this design pattern is inherently fragile.\n+\n+Hopefully it's clear by now why unconditionally overriding state with props is a bad idea. But what if we were to only update the state when the email prop changes? We'll take a look at that pattern next.\n+\n+### Anti-pattern: Props override state whenever they change\n+\n+Building on our example above, we could avoid accidentally erasing state by only updating it when `props.email` changes:\n+\n+```js\n+class EmailInput extends Component {\n+  state = {\n+    prevPropsEmail: this.props.email,\n+    email: this.props.email\n+  };\n+\n+  static getDerivedStateFromProps(props, state) {\n+    // Any time props.email changes, update state.\n+    if (props.email !== state.prevPropsEmail) {\n+      return {\n+        prevPropsEmail: props.email,\n+        email: props.email\n+      };\n+    }\n+    return null;\n+  }\n+  \n+  // ...\n+}\n+```\n+\n+We've just made a big improvement. Now our component will no longer erase what we've typed every time it renders. At this point, what we have is fairly similar to the [scroll direction example](blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props) we mentioned before. (It will also more closely mirror how `componentWillReceiveProps` would have been used in the past.)\n+\n+There is still one subtle problem though, and it's probably easiest to illustrate with an example. Let's say our `EmailInput` component is used inside of an \"edit profile\" form. The first time the form is rendered, the component will display our email address. Let's say we edited the form (including our email address) but then changed our mind and clicked a \"reset\" button. At this point, we would expect all form fields to return to their initial values– but the `EmailInput` component **will not be reset**. Do you know why?\n+\n+The reason for this is that `props.email` never actually changed in the above scenario. Both times the \"edit profile\" form rendered, it would pass our saved email address via props.\n+\n+This design is fundamentally flawed, but it's an easy mistake to make. [I've made it myself.](https://twitter.com/brian_d_vaughn/status/959600888242307072) Fortunately there are two alternatives that work better. The key to both is for **state to only be owned by a single component**. Let's take a look at each.","path":"content/blog/2018-06-07-when-to-use-derived-state.md","position":118,"original_position":118,"commit_id":"1d82c291fed748504c7d0d83d36db382c476fe8c","original_commit_id":"1d82c291fed748504c7d0d83d36db382c476fe8c","user":{"login":"bvaughn","id":29597,"node_id":"MDQ6VXNlcjI5NTk3","avatar_url":"https://avatars0.githubusercontent.com/u/29597?v=4","gravatar_id":"","url":"https://api.github.com/users/bvaughn","html_url":"https://github.com/bvaughn","followers_url":"https://api.github.com/users/bvaughn/followers","following_url":"https://api.github.com/users/bvaughn/following{/other_user}","gists_url":"https://api.github.com/users/bvaughn/gists{/gist_id}","starred_url":"https://api.github.com/users/bvaughn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bvaughn/subscriptions","organizations_url":"https://api.github.com/users/bvaughn/orgs","repos_url":"https://api.github.com/users/bvaughn/repos","events_url":"https://api.github.com/users/bvaughn/events{/privacy}","received_events_url":"https://api.github.com/users/bvaughn/received_events","type":"User","site_admin":false},"body":"👍 ","created_at":"2018-06-05T20:53:24Z","updated_at":"2018-06-05T20:53:24Z","html_url":"https://github.com/reactjs/reactjs.org/pull/931#discussion_r193218530","pull_request_url":"https://api.github.com/repos/reactjs/reactjs.org/pulls/931","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/reactjs/reactjs.org/pulls/comments/193218530"},"html":{"href":"https://github.com/reactjs/reactjs.org/pull/931#discussion_r193218530"},"pull_request":{"href":"https://api.github.com/repos/reactjs/reactjs.org/pulls/931"}},"in_reply_to_id":193186630},"pull_request":{"url":"https://api.github.com/repos/reactjs/reactjs.org/pulls/931","id":192783260,"node_id":"MDExOlB1bGxSZXF1ZXN0MTkyNzgzMjYw","html_url":"https://github.com/reactjs/reactjs.org/pull/931","diff_url":"https://github.com/reactjs/reactjs.org/pull/931.diff","patch_url":"https://github.com/reactjs/reactjs.org/pull/931.patch","issue_url":"https://api.github.com/repos/reactjs/reactjs.org/issues/931","number":931,"state":"open","locked":false,"title":"Blog: When to Use Derived State","user":{"login":"bvaughn","id":29597,"node_id":"MDQ6VXNlcjI5NTk3","avatar_url":"https://avatars0.githubusercontent.com/u/29597?v=4","gravatar_id":"","url":"https://api.github.com/users/bvaughn","html_url":"https://github.com/bvaughn","followers_url":"https://api.github.com/users/bvaughn/followers","following_url":"https://api.github.com/users/bvaughn/following{/other_user}","gists_url":"https://api.github.com/users/bvaughn/gists{/gist_id}","starred_url":"https://api.github.com/users/bvaughn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bvaughn/subscriptions","organizations_url":"https://api.github.com/users/bvaughn/orgs","repos_url":"https://api.github.com/users/bvaughn/repos","events_url":"https://api.github.com/users/bvaughn/events{/privacy}","received_events_url":"https://api.github.com/users/bvaughn/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-06-05T17:34:08Z","updated_at":"2018-06-05T20:53:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6b69bb3b31268addb376400d702d0f6f8ba4472d","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":712729626,"node_id":"MDU6TGFiZWw3MTI3Mjk2MjY=","url":"https://api.github.com/repos/reactjs/reactjs.org/labels/CLA%20Signed","name":"CLA Signed","color":"e7e7e7","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/reactjs/reactjs.org/pulls/931/commits","review_comments_url":"https://api.github.com/repos/reactjs/reactjs.org/pulls/931/comments","review_comment_url":"https://api.github.com/repos/reactjs/reactjs.org/pulls/comments{/number}","comments_url":"https://api.github.com/repos/reactjs/reactjs.org/issues/931/comments","statuses_url":"https://api.github.com/repos/reactjs/reactjs.org/statuses/1d82c291fed748504c7d0d83d36db382c476fe8c","head":{"label":"bvaughn:when-to-use-derived-state","ref":"when-to-use-derived-state","sha":"1d82c291fed748504c7d0d83d36db382c476fe8c","user":{"login":"bvaughn","id":29597,"node_id":"MDQ6VXNlcjI5NTk3","avatar_url":"https://avatars0.githubusercontent.com/u/29597?v=4","gravatar_id":"","url":"https://api.github.com/users/bvaughn","html_url":"https://github.com/bvaughn","followers_url":"https://api.github.com/users/bvaughn/followers","following_url":"https://api.github.com/users/bvaughn/following{/other_user}","gists_url":"https://api.github.com/users/bvaughn/gists{/gist_id}","starred_url":"https://api.github.com/users/bvaughn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bvaughn/subscriptions","organizations_url":"https://api.github.com/users/bvaughn/orgs","repos_url":"https://api.github.com/users/bvaughn/repos","events_url":"https://api.github.com/users/bvaughn/events{/privacy}","received_events_url":"https://api.github.com/users/bvaughn/received_events","type":"User","site_admin":false},"repo":{"id":106025325,"node_id":"MDEwOlJlcG9zaXRvcnkxMDYwMjUzMjU=","name":"reactjs.org","full_name":"bvaughn/reactjs.org","owner":{"login":"bvaughn","id":29597,"node_id":"MDQ6VXNlcjI5NTk3","avatar_url":"https://avatars0.githubusercontent.com/u/29597?v=4","gravatar_id":"","url":"https://api.github.com/users/bvaughn","html_url":"https://github.com/bvaughn","followers_url":"https://api.github.com/users/bvaughn/followers","following_url":"https://api.github.com/users/bvaughn/following{/other_user}","gists_url":"https://api.github.com/users/bvaughn/gists{/gist_id}","starred_url":"https://api.github.com/users/bvaughn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bvaughn/subscriptions","organizations_url":"https://api.github.com/users/bvaughn/orgs","repos_url":"https://api.github.com/users/bvaughn/repos","events_url":"https://api.github.com/users/bvaughn/events{/privacy}","received_events_url":"https://api.github.com/users/bvaughn/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bvaughn/reactjs.org","description":"Source code and documentation powering reactjs.org","fork":true,"url":"https://api.github.com/repos/bvaughn/reactjs.org","forks_url":"https://api.github.com/repos/bvaughn/reactjs.org/forks","keys_url":"https://api.github.com/repos/bvaughn/reactjs.org/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bvaughn/reactjs.org/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bvaughn/reactjs.org/teams","hooks_url":"https://api.github.com/repos/bvaughn/reactjs.org/hooks","issue_events_url":"https://api.github.com/repos/bvaughn/reactjs.org/issues/events{/number}","events_url":"https://api.github.com/repos/bvaughn/reactjs.org/events","assignees_url":"https://api.github.com/repos/bvaughn/reactjs.org/assignees{/user}","branches_url":"https://api.github.com/repos/bvaughn/reactjs.org/branches{/branch}","tags_url":"https://api.github.com/repos/bvaughn/reactjs.org/tags","blobs_url":"https://api.github.com/repos/bvaughn/reactjs.org/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bvaughn/reactjs.org/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bvaughn/reactjs.org/git/refs{/sha}","trees_url":"https://api.github.com/repos/bvaughn/reactjs.org/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bvaughn/reactjs.org/statuses/{sha}","languages_url":"https://api.github.com/repos/bvaughn/reactjs.org/languages","stargazers_url":"https://api.github.com/repos/bvaughn/reactjs.org/stargazers","contributors_url":"https://api.github.com/repos/bvaughn/reactjs.org/contributors","subscribers_url":"https://api.github.com/repos/bvaughn/reactjs.org/subscribers","subscription_url":"https://api.github.com/repos/bvaughn/reactjs.org/subscription","commits_url":"https://api.github.com/repos/bvaughn/reactjs.org/commits{/sha}","git_commits_url":"https://api.github.com/repos/bvaughn/reactjs.org/git/commits{/sha}","comments_url":"https://api.github.com/repos/bvaughn/reactjs.org/comments{/number}","issue_comment_url":"https://api.github.com/repos/bvaughn/reactjs.org/issues/comments{/number}","contents_url":"https://api.github.com/repos/bvaughn/reactjs.org/contents/{+path}","compare_url":"https://api.github.com/repos/bvaughn/reactjs.org/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bvaughn/reactjs.org/merges","archive_url":"https://api.github.com/repos/bvaughn/reactjs.org/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bvaughn/reactjs.org/downloads","issues_url":"https://api.github.com/repos/bvaughn/reactjs.org/issues{/number}","pulls_url":"https://api.github.com/repos/bvaughn/reactjs.org/pulls{/number}","milestones_url":"https://api.github.com/repos/bvaughn/reactjs.org/milestones{/number}","notifications_url":"https://api.github.com/repos/bvaughn/reactjs.org/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bvaughn/reactjs.org/labels{/name}","releases_url":"https://api.github.com/repos/bvaughn/reactjs.org/releases{/id}","deployments_url":"https://api.github.com/repos/bvaughn/reactjs.org/deployments","created_at":"2017-10-06T16:15:47Z","updated_at":"2017-10-06T16:15:49Z","pushed_at":"2018-06-05T18:46:30Z","git_url":"git://github.com/bvaughn/reactjs.org.git","ssh_url":"git@github.com:bvaughn/reactjs.org.git","clone_url":"https://github.com/bvaughn/reactjs.org.git","svn_url":"https://github.com/bvaughn/reactjs.org","homepage":"https://reactjs.org/","size":66523,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"cc-by-4.0","name":"Creative Commons Attribution 4.0","spdx_id":"CC-BY-4.0","url":"https://api.github.com/licenses/cc-by-4.0","node_id":"MDc6TGljZW5zZTI1"},"forks":1,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"reactjs:master","ref":"master","sha":"e39975e48135876059e8f8299d8cfb1f1699b092","user":{"login":"reactjs","id":6412038,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY0MTIwMzg=","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":105963253,"node_id":"MDEwOlJlcG9zaXRvcnkxMDU5NjMyNTM=","name":"reactjs.org","full_name":"reactjs/reactjs.org","owner":{"login":"reactjs","id":6412038,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY0MTIwMzg=","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/reactjs.org","description":"The React documentation website","fork":false,"url":"https://api.github.com/repos/reactjs/reactjs.org","forks_url":"https://api.github.com/repos/reactjs/reactjs.org/forks","keys_url":"https://api.github.com/repos/reactjs/reactjs.org/keys{/key_id}","collaborators_url":"https://api.github.com/repos/reactjs/reactjs.org/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/reactjs/reactjs.org/teams","hooks_url":"https://api.github.com/repos/reactjs/reactjs.org/hooks","issue_events_url":"https://api.github.com/repos/reactjs/reactjs.org/issues/events{/number}","events_url":"https://api.github.com/repos/reactjs/reactjs.org/events","assignees_url":"https://api.github.com/repos/reactjs/reactjs.org/assignees{/user}","branches_url":"https://api.github.com/repos/reactjs/reactjs.org/branches{/branch}","tags_url":"https://api.github.com/repos/reactjs/reactjs.org/tags","blobs_url":"https://api.github.com/repos/reactjs/reactjs.org/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/reactjs/reactjs.org/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/reactjs/reactjs.org/git/refs{/sha}","trees_url":"https://api.github.com/repos/reactjs/reactjs.org/git/trees{/sha}","statuses_url":"https://api.github.com/repos/reactjs/reactjs.org/statuses/{sha}","languages_url":"https://api.github.com/repos/reactjs/reactjs.org/languages","stargazers_url":"https://api.github.com/repos/reactjs/reactjs.org/stargazers","contributors_url":"https://api.github.com/repos/reactjs/reactjs.org/contributors","subscribers_url":"https://api.github.com/repos/reactjs/reactjs.org/subscribers","subscription_url":"https://api.github.com/repos/reactjs/reactjs.org/subscription","commits_url":"https://api.github.com/repos/reactjs/reactjs.org/commits{/sha}","git_commits_url":"https://api.github.com/repos/reactjs/reactjs.org/git/commits{/sha}","comments_url":"https://api.github.com/repos/reactjs/reactjs.org/comments{/number}","issue_comment_url":"https://api.github.com/repos/reactjs/reactjs.org/issues/comments{/number}","contents_url":"https://api.github.com/repos/reactjs/reactjs.org/contents/{+path}","compare_url":"https://api.github.com/repos/reactjs/reactjs.org/compare/{base}...{head}","merges_url":"https://api.github.com/repos/reactjs/reactjs.org/merges","archive_url":"https://api.github.com/repos/reactjs/reactjs.org/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/reactjs/reactjs.org/downloads","issues_url":"https://api.github.com/repos/reactjs/reactjs.org/issues{/number}","pulls_url":"https://api.github.com/repos/reactjs/reactjs.org/pulls{/number}","milestones_url":"https://api.github.com/repos/reactjs/reactjs.org/milestones{/number}","notifications_url":"https://api.github.com/repos/reactjs/reactjs.org/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/reactjs/reactjs.org/labels{/name}","releases_url":"https://api.github.com/repos/reactjs/reactjs.org/releases{/id}","deployments_url":"https://api.github.com/repos/reactjs/reactjs.org/deployments","created_at":"2017-10-06T03:16:04Z","updated_at":"2018-06-05T19:34:50Z","pushed_at":"2018-06-05T18:46:32Z","git_url":"git://github.com/reactjs/reactjs.org.git","ssh_url":"git@github.com:reactjs/reactjs.org.git","clone_url":"https://github.com/reactjs/reactjs.org.git","svn_url":"https://github.com/reactjs/reactjs.org","homepage":"https://reactjs.org/","size":66509,"stargazers_count":1793,"watchers_count":1793,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1254,"mirror_url":null,"archived":false,"open_issues_count":229,"license":{"key":"cc-by-4.0","name":"Creative Commons Attribution 4.0","spdx_id":"CC-BY-4.0","url":"https://api.github.com/licenses/cc-by-4.0","node_id":"MDc6TGljZW5zZTI1"},"forks":1254,"open_issues":229,"watchers":1793,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/reactjs/reactjs.org/pulls/931"},"html":{"href":"https://github.com/reactjs/reactjs.org/pull/931"},"issue":{"href":"https://api.github.com/repos/reactjs/reactjs.org/issues/931"},"comments":{"href":"https://api.github.com/repos/reactjs/reactjs.org/issues/931/comments"},"review_comments":{"href":"https://api.github.com/repos/reactjs/reactjs.org/pulls/931/comments"},"review_comment":{"href":"https://api.github.com/repos/reactjs/reactjs.org/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/reactjs/reactjs.org/pulls/931/commits"},"statuses":{"href":"https://api.github.com/repos/reactjs/reactjs.org/statuses/1d82c291fed748504c7d0d83d36db382c476fe8c"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"bvaughn"}}