Mastering React: From Transformation to Algebraic Effects
This article walks front‑end developers through the author's deductive model of React, covering transformation, abstraction, composition, state handling, memoization, list management, continuations, state maps, and algebraic effects with clear code examples.
21CTO community guide: React certificate issues are solved, more companies adopt React, and interactive front‑end programming is booming. The author shares the original thinking behind the React framework to benefit developers.
The author attempts to explain their understanding of the React model using deductive reasoning, acknowledging controversial preconditions and inviting improvements via pull requests.
Transformation
React assumes UI is a deterministic mapping from data to view.
function NameBox(name) {
return { fontWeight: 'bold', labelContent: name };
}
'Sebastian Markbåge' -> { fontWeight: 'bold', labelContent: 'Sebastian Markbåge' };Abstraction
Complex UI should be broken into reusable abstract components.
function FancyUserBox(user) {
return {
borderStyle: '1px solid blue',
childContent: [
'Name: ',
NameBox(user.firstName + ' ' + user.lastName)
]
};
}
{ firstName: 'Sebastian', lastName: 'Markbåge' } -> {
borderStyle: '1px solid blue',
childContent: [
'Name: ',
{ fontWeight: 'bold', labelContent: 'Sebastian Markbåge' }
]
};Composition
Reusable containers can be composed to form higher‑level abstractions.
function FancyBox(children) {
return { borderStyle: '1px solid blue', children: children };
}
function UserBox(user) {
return FancyBox([
'Name: ',
NameBox(user.firstName + ' ' + user.lastName)
]);
}State
UI state is often local and immutable; updates flow from the top.
function FancyNameBox(user, likes, onClick) {
return FancyBox([
'Name: ',
NameBox(user.firstName + ' ' + user.lastName),
'Likes: ',
LikeBox(likes),
LikeButton(onClick)
]);
}
var likes = 0;
function addOneMoreLike() { likes++; rerender(); }
FancyNameBox({ firstName: 'Sebastian', lastName: 'Markbåge' }, likes, addOneMoreLike);Lists
Lists are natural structures; a Map can store per‑item state.
function UserList(users, likesPerUser, updateUserLikes) {
return users.map(user =>
FancyNameBox(
user,
likesPerUser.get(user.id),
() => 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);Continuations
Binding functions (currying) moves repetitive boilerplate out of core logic.
function FancyUserList(users) {
return FancyBox(
UserList.bind(null, users)
);
}
const box = FancyUserList(data.users);
const resolvedChildren = box.children(likesPerUser, updateUserLikes);
const resolvedBox = { ...box, children: resolvedChildren };State Map
Extracting state handling into a lower‑level function enables reusable patterns.
function FancyBoxWithState(children, stateMap, updateState) {
return FancyBox(
children.map(child => child.continuation(stateMap.get(child.key), updateState))
);
}
function UserList(users) {
return users.map(user => ({
continuation: FancyNameBox.bind(null, user),
key: user.id
}));
}
function FancyUserList(users) {
return FancyBoxWithState.bind(null, UserList(users));
}
const continuation = FancyUserList(data.users);
continuation(likesPerUser, updateUserLikes);Memoization Map
Caching multiple items requires sophisticated algorithms; tree stability aids memoization.
function memoize(fn) {
return function(arg, memoizationCache) {
if (memoizationCache.arg === arg) {
return memoizationCache.result;
}
const result = fn(arg);
memoizationCache.arg = arg;
memoizationCache.result = result;
return result;
};
}
function FancyBoxWithState(children, stateMap, updateState, memoizationCache) {
return FancyBox(
children.map(child => child.continuation(
stateMap.get(child.key),
updateState,
memoizationCache.get(child.key)
))
);
}
const MemoizedFancyNameBox = memoize(FancyNameBox);Algebraic Effects
React can be modeled with algebraic effects to short‑circuit context propagation.
function ThemeBorderColorRequest() {}
function FancyBox(children) {
const color = raise new ThemeBorderColorRequest();
return { borderWidth: '1px', borderColor: color, children: children };
}
function BlueTheme(children) {
try { children(); }
catch (effect ThemeBorderColorRequest -> [, continuation]) {
continuation('blue');
}
}
function App(data) {
return BlueTheme(
FancyUserList.bind(null, data.users)
);
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
