forked from facebook/react
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Blocks] Add Client Fixture (facebook#18773)
* [Blocks] Add Client Fixture * Add more TODOs
- Loading branch information
Showing
12 changed files
with
11,500 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
SKIP_PREFLIGHT_CHECK=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{ | ||
"posts": [ | ||
{ | ||
"id": 1, | ||
"title": "My First Post", | ||
"body": "Hello, world!" | ||
}, | ||
{ | ||
"id": 2, | ||
"title": "My Second Post", | ||
"body": "Let me tell you everything about useEffect" | ||
}, | ||
{ | ||
"id": 3, | ||
"title": "My Third Post", | ||
"body": "Why is everything so complicated?" | ||
} | ||
], | ||
"comments": [ | ||
{ | ||
"id": 1, | ||
"body": "Hey there", | ||
"postId": 1 | ||
}, | ||
{ | ||
"id": 2, | ||
"body": "Welcome to the chat", | ||
"postId": 1 | ||
}, | ||
{ | ||
"id": 3, | ||
"body": "What editor/font are you using?", | ||
"postId": 2 | ||
}, | ||
{ | ||
"id": 4, | ||
"body": "It's always been hard", | ||
"postId": 3 | ||
}, | ||
{ | ||
"id": 5, | ||
"body": "It's still easy", | ||
"postId": 3 | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"name": "blocks", | ||
"version": "0.1.0", | ||
"private": true, | ||
"dependencies": { | ||
"concurrently": "^5.2.0", | ||
"json-server": "^0.16.1", | ||
"react": "^16.13.1", | ||
"react-dom": "^16.13.1", | ||
"react-scripts": "3.4.1" | ||
}, | ||
"scripts": { | ||
"prestart": "cp -r ../../build/node_modules/* ./node_modules/", | ||
"prebuild": "cp -r ../../build/node_modules/* ./node_modules/", | ||
"start": "concurrently \"npm run start:client\" \"npm run start:api\"", | ||
"start:api": "json-server --watch db.json --port 3001 --delay 300", | ||
"start:client": "react-scripts start", | ||
"build": "react-scripts build", | ||
"eject": "react-scripts eject" | ||
}, | ||
"eslintConfig": { | ||
"extends": "react-app" | ||
}, | ||
"browserslist": { | ||
"production": [ | ||
">0.2%", | ||
"not dead", | ||
"not op_mini all" | ||
], | ||
"development": [ | ||
"last 1 chrome version", | ||
"last 1 firefox version", | ||
"last 1 safari version" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<title>Blocks Fixture</title> | ||
</head> | ||
<body> | ||
<noscript>You need to enable JavaScript to run this app.</noscript> | ||
<div id="root"></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import React, {useReducer, useTransition, Suspense} from 'react'; | ||
import loadPost from './Post'; | ||
import {createCache, CacheProvider} from './lib/cache'; | ||
|
||
const initialState = { | ||
cache: createCache(), | ||
params: {id: 1}, | ||
RootBlock: loadPost({id: 1}), | ||
}; | ||
|
||
function reducer(state, action) { | ||
switch (action.type) { | ||
case 'navigate': | ||
// TODO: cancel previous fetch? | ||
return { | ||
cache: state.cache, | ||
params: action.nextParams, | ||
RootBlock: loadPost(action.nextParams), | ||
}; | ||
default: | ||
throw new Error(); | ||
} | ||
} | ||
|
||
function Router() { | ||
const [state, dispatch] = useReducer(reducer, initialState); | ||
const [startTransition, isPending] = useTransition({ | ||
timeoutMs: 3000, | ||
}); | ||
return ( | ||
<> | ||
<button | ||
disabled={isPending} | ||
onClick={() => { | ||
startTransition(() => { | ||
dispatch({ | ||
type: 'navigate', | ||
nextParams: { | ||
id: state.params.id === 3 ? 1 : state.params.id + 1, | ||
}, | ||
}); | ||
}); | ||
}}> | ||
Next | ||
</button> | ||
{isPending && ' ...'} | ||
<hr /> | ||
<Suspense fallback={<h4>Loading Page...</h4>}> | ||
<CacheProvider value={state.cache}> | ||
<state.RootBlock /> | ||
</CacheProvider> | ||
</Suspense> | ||
</> | ||
); | ||
} | ||
|
||
function Root() { | ||
return ( | ||
<Suspense fallback={<h1>Loading App...</h1>}> | ||
<Router /> | ||
</Suspense> | ||
); | ||
} | ||
|
||
export default Root; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import * as React from 'react'; | ||
import {fetch} from './lib/data'; | ||
|
||
function load(postId) { | ||
return { | ||
comments: fetch('http://localhost:3001/comments?postId=' + postId), | ||
}; | ||
} | ||
|
||
function Comments(props, data) { | ||
return ( | ||
<> | ||
<h3>Comments</h3> | ||
<ul> | ||
{data.comments.slice(0, 5).map(item => ( | ||
<li key={item.id}>{item.body}</li> | ||
))} | ||
</ul> | ||
</> | ||
); | ||
} | ||
|
||
export default React.block(Comments, load); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import * as React from 'react'; | ||
import {block, Suspense} from 'react'; | ||
import {fetch} from './lib/data'; | ||
import loadComments from './Comments'; | ||
|
||
function load(params) { | ||
return { | ||
post: fetch('http://localhost:3001/posts/' + params.id), | ||
Comments: loadComments(params.id), | ||
}; | ||
} | ||
|
||
function Post(props, data) { | ||
return ( | ||
<> | ||
<h1>Post {data.post.id}</h1> | ||
<h4>{data.post.title}</h4> | ||
<p>{data.post.body}</p> | ||
<hr /> | ||
<Suspense fallback={<p>Loading comments...</p>}> | ||
<data.Comments /> | ||
</Suspense> | ||
</> | ||
); | ||
} | ||
|
||
export default block(Post, load); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
body { | ||
font-family: Helvetica; | ||
padding-left: 10px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import './index.css'; | ||
import App from './App'; | ||
|
||
ReactDOM.createRoot(document.getElementById('root')).render(<App />); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import {createContext} from 'react'; | ||
|
||
// TODO: clean up and move to react/cache. | ||
|
||
// TODO: cancellation token. | ||
|
||
// TODO: does there need to be default context? | ||
|
||
const CacheContext = createContext(null); | ||
|
||
export const CacheProvider = CacheContext.Provider; | ||
|
||
// TODO: use this for invalidation. | ||
|
||
export function createCache() { | ||
return new Map(); | ||
} | ||
|
||
export function readCache() { | ||
// TODO: this doesn't subscribe. | ||
// But we really want load context anyway. | ||
return CacheContext._currentValue; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/** | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
import {readCache} from './cache'; | ||
|
||
// TODO: clean up and move to react-data/fetch. | ||
|
||
// TODO: some other data provider besides fetch. | ||
|
||
// TODO: base agnostic helper like createResource. Maybe separate. | ||
|
||
let sigil = {}; | ||
|
||
function readFetchMap() { | ||
const cache = readCache(); | ||
if (!cache.has(sigil)) { | ||
cache.set(sigil, new Map()); | ||
} | ||
return cache.get(sigil); | ||
} | ||
|
||
export function fetch(url) { | ||
const map = readFetchMap(); | ||
let entry = map.get(url); | ||
if (entry === undefined) { | ||
entry = { | ||
status: 'pending', | ||
result: new Promise(resolve => { | ||
let xhr = new XMLHttpRequest(); | ||
xhr.onload = function() { | ||
entry.result = JSON.parse(xhr.response); | ||
entry.status = 'resolved'; | ||
resolve(); | ||
}; | ||
xhr.onerror = function(err) { | ||
entry.result = err; | ||
entry.status = 'rejected'; | ||
resolve(); | ||
}; | ||
xhr.open('GET', url); | ||
xhr.send(); | ||
}), | ||
}; | ||
map.set(url, entry); | ||
} | ||
switch (entry.status) { | ||
case 'resolved': | ||
return entry.result; | ||
case 'pending': | ||
case 'rejected': | ||
throw entry.result; | ||
default: | ||
throw new Error(); | ||
} | ||
} |
Oops, something went wrong.