https://github.com/reactjs/react-basic/blob/master/README.md
function NameBox(name) {
return { fontWeight: 'bold', labelContent: name };
}
// Level 1 reuse: Show user name with blue border
function FancyUserBox(user) {
return {
borderStyle: '1px solid blue',
childContent: [
'Name: ',
NameBox(user.firstName + ' ' + user.lastName)
]
};
}
// Level 2 reuse: Create an abstraction about a bordered box with any children
function FancyBox(children) {
return {
borderStyle: '1px solid blue',
children: children
};
}
// A concret implementation for a UserBox show user's name with blue border provided by fancy box
function UserBox(user) {
return FancyBox([
'Name: ',
NameBox(user.firstName + ' ' + user.lastName)
]);
}
// Introduce state with react component
// Superior version of UserBox with like count and like button
function FancyNameBox(user, likes, onClick) {
return FancyBox([
'Name: ', NameBox(user.firstName + ' ' + user.lastName),
'Likes: ', LikeBox(likes),
LikeButton(onClick)
]);
}
// Implementation Details
var likes = 0;
function addOneMoreLike() {
likes++;
rerender();
}
// Init
FancyNameBox(
{ firstName: 'Sebastian', lastName: 'Markbage' },
likes,
addOneMoreLike
);
// Memoization => Avoid wasting resources on same computations if function is pure at first
function memoize(fn) {
var cachedArg;
var cachedResult;
return function(arg) {
if (cachedArg === arg) {
return cachedResult;
}
cachedArg = arg;
cachedResult = fn(arg);
return cachedResult;
};
}
// Return the same name box with same argument => Avoid useless computations
var MemoizedNameBox = memoize(NameBox);
// A variant of FancyBox with Name box plus Age
function NameAndAgeBox(user, currentTime) {
return FancyBox([
'Name: ',
MemoizedNameBox(user.firstName + ' ' + user.lastName),
'Age in milliseconds: ',
currentTime - user.dateOfBirth
]);
}
// Introduce concept of list
// Create a list of FancyNameBox with a list of user's data and a map of like count with user id
function UserList(users, likesPerUser, updateUserLikes) {
return users.map(user => FancyNameBox(
user,
likesPerUser.get(user.id),
// Defer the updateUserLikes with sufficient data for computation => wraps itself as on Click
() => updateUserLikes(user.id, likesPerUser.get(user.id) + 1)
));
}
var likesPerUser = new Map();
function updateUserLikes(id, likeCount) {
likesPerUser.set(id, likeCount);
rerender();
}
UserList(data.users, likesPerUser, updateUserLikes);
// No memorization at this point as it can memorize one value at a time
// Continuations
// Defer the concret instantiation of user list => fancy user list
function FancyUserList(users) {
return FancyBox(
UserList.bind(null, users)
);
}
// Defer the instantiation of UserList such that likes and callback can provided later on
const box = FancyUserList(data.users);
// Instantiate UserList (finally) by providing like counts and callback
const resolvedChildren = box.children(likesPerUser, updateUserLikes);
// Final FancyBox with user list
const resolvedBox = {
...box,
children: resolvedChildren
};
// TODO: State map, Memorization map, Algebraic Effects