GithubHelp home page GithubHelp logo

react-mini's Introduction

React Mini

React is truely amazing.

At first, it's a bit weird. Then you develop an intuition and everything works the way you expect it to. At some point you start asking questions. Then it's really weird.

  • Why is it possible to use useState multiple times?

    Turns out that the call order is used to distinguish calls, this is why they must appear on the top level.

  • How does an <input /> element retain focus if onChange modifies the value attribute?

    The component should re-render and a new element should be created. If there are multiple, how does React know which one should be focused?

    Turns out that it matches the elements from the previous render with the elements of the current render. Then it simply updates the attributes of that element without re-creating it, that retains the focus.

  • ...

I am certainly not the first to ask these questions. There many are answers avaliable online.

However, this caught my interest and I created my own simplified implementation of React. This is based primarily on blog articles that discuss the internals of React. I didn't look at the source code of React much.

If you are looking for an accurate description of how React works, this probably isn't it.

Setup

Install dependencies with yarn install and run with yarn start. This should open a web-browser at http://localhost:8001 by default.

Details

In index.jsx there are some components defined that should look familiar to React developers. But instead of using React, all the code has been implemented by myself. The syntax is slightly different, because I require a key attribute to be always present.

There is a bit of magic going on behind the scenes. I use @web/dev-server-esbuild to parse the JSX syntax and to generate matching JavaScript code. This is configured in web-dev-server.config.mjs and is explained further in react-mini.js when jsx_createComponent is defined.

If you are reading through the code, the mount function is the entry point, this is similar to ReactDOM.createRoot(/* ... */).render(/* ... */) in React.

It is also possible to use the library without JSX which may be more intuitive:

import {
    mount,
    ComponentNode,
    HtmlNode,
    TextNode
} from "./react-mini.js";

/*
function IncrementComponent(properties, useState) {
    let [counter, setCounter] = useState(0);
    return (
        <div key={properties.key}>
            <p key="1">Counter: {counter}</p>
            <button key="2" $click={() => setCounter(counter + 1)}>
                Increment
            </button>
        </div>
    );
}

mount(
    document.getElementById("root-container"),
    <IncrementComponent key="root" />,
);
*/
mount(
    document.getElementById("root-container"),
    new ComponentNode({
        componentFunction: ({ properties, useState}) => {
            let [counter, setCounter] = useState(0);

            return new HtmlNode({
                elementType: "div",
                properties: {
                    key: properties.key,
                },
                children: [
                    new HtmlNode({
                        elementType: "p",
                        properties: {
                            key: "1",
                        },
                        children: [
                            new TextNode({
                                text: `Counter: ${counter}`,
                            }),
                        ],
                    }),
                    new HtmlNode({
                        elementType: "button",
                        properties: {
                            key: "2",
                            $click: () => setCounter(counter + 1),
                        },
                        children: [
                            new TextNode({
                                text: "Increment",
                            }),
                        ],
                    }),
                ],
            });
        },
        properties: {
            key: "root",
        },
    }),
);

react-mini's People

Contributors

asynts avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.