DEV Community

Cover image for I designed a React props feature for my own web framework
Uriel Bitton
Uriel Bitton

Posted on

I designed a React props feature for my own web framework

After learning React about 2 years ago, I really loved the way the props feature works, amongst its myriad features of course. But the props feature was especially impressive to me as it helped me solve problems i usually encountered when designing websites and web apps in the past.

So this inspired me to design my own web framework, I called it Reactor, and it would be capable of rendering props just like react, without the heavy framework react brings and it would be used with a simple cdn link.

So let's have a look at the code that i wrote.
(I should mention i wrote it in jquery as i was in my prime of jquery at the time - 2 years ago. I'm actually working on refactoring it all to Vanilla JS to remove the dependency on jquery).

function propsDesign() {    
//remove reactor models    
$('head').append('<style>.reactor,reactor-vars, reactor-links,reactor-imgs, reactor-hidden, reactor-container{display:none}</style>'); 
var appid = {};      
var reactorapp = $('.reactorapp');
var appnum = reactorapp.length;       
$('.reactor-special').fadeOut(0);          

//big appnum for loop     
for(k=0;k<appnum;k++) {    
$('.re-app').eq(k).addClass('re-app'+k);
var featflex = {};    
var rcont = $('reactor-container').html();  
rcont = rcont.replace(/\s/g, '');
rcont = rcont.replace(new RegExp('{|}', 'g'),"");     
var featflexsize = $('.re-app'+k+' '+rcont).length;     
var reactor = $('.re-app'+k+' .reactor').html();  
var reactorvars = $('.re-app'+k+' reactor-vars');  
//imgs
if($('.re-app'+k+' reactor-imgs').length > 0) {      
var imgprops = $('.re-app'+k+' reactor-imgs').html();    
imgprops = imgprops.replace(/\s/g, '');
imgprops = imgprops.replace(new RegExp('{|}', 'g'),"");  
var imgpropsarray = imgprops.split(',');
}
//links
if($('.re-app'+k+' reactor-links').length > 0) {      
var linksprops = $('.re-app'+k+' reactor-links').html();    
linksprops = linksprops.replace(/\s/g, '');
linksprops = linksprops.replace(new RegExp('{|}', 'g'),"");  
var linkspropsarray = linksprops.split(',');
}
var props = reactorvars.html();    
props = props.replace(new RegExp('{|}', 'g'),"");     
props = props.replace(/\s/g, '');  
var propsarray = props.split(','); 
var reactarray = {}; 
var reactimgarray = {};
var reactlinksarray = {};
var replacer = {};       

for(i=0;i<featflexsize;i++) {
    featflex[i] = $('.re-app'+k+' '+rcont+':nth-of-type('+(i+1)+')');
    featflex[i].html(reactor);
    for(j=0;j<propsarray.length;j++) {
        reactarray[j] = featflex[i].data(propsarray[j]);
    } 
    if($('.re-app'+k+' reactor-imgs').length > 0) { 
        for(j=0;j<imgpropsarray.length;j++) {
            reactimgarray[j] = featflex[i].data(imgpropsarray[j]);
            $('.re-app'+k+' '+rcont+':nth-of-type('+(i+1)+')').find('img:eq('+j+')').filter(function() {
                return this.innerHTML = '{'+imgpropsarray[j]+'}';  
            }).attr('src', reactimgarray[j]);   
        }    
    }     
    if($('.re-app'+k+' reactor-links').length > 0) { 
        for(j=0;j<linkspropsarray.length;j++) {
            reactlinksarray[j] = featflex[i].data(linkspropsarray[j]);
            $('.re-app'+k+' '+rcont+':nth-of-type('+(i+1)+')').find('a:eq('+j+')').filter(function() {
                return this.innerHTML = '{'+linkspropsarray[j]+'}';  
            }).attr('href', reactlinksarray[j]);   
        }    
    }
    for(j=0;j<propsarray.length;j++) {
        $('.re-app'+k+' '+rcont+':nth-of-type('+(i+1)+')').find('*').filter(function() {
            return this.innerHTML == '{'+propsarray[j]+'}';     
        }).html(reactarray[j]); 
    }
    if($('[reactor-special]').length) {
        $('[reactor-special]').find('.reactor-special').fadeIn(0); 
    }

}  
}  
//end of big appnum for loop  
}//end of propsDesign function
Enter fullscreen mode Exit fullscreen mode

Let's explain in small portions how the code works. Needless to say, it is extremely complex, but that level of complexity was needed in order to make the framework work.

In essence, the code searches for divs with the class "re-app" and takes the "parameters" provided inside the html element "react-vars". The parameters inside that element are the "text props". Then it does the same for the parameters inside the element "react-links" and "react-imgs". Once it collects all those "props" values it applies them to the template div component which you specify with the mandatory class "reactor". It fills in the props values inside the html elements, like h1, p, span, etc and the image source inside the img src attribute, the links inside the html a href attribute and then renders that template as many times as you add it on the regular html page.

Let's see a quick example that will help you understand what's going on.

<div class="re-app">

    <div class="reactorapp">

        <my-products data-img1="images/p1.jpg" data-title="Women's Dresses" data-price="$450.00" data-link="https://reactor-js.com/p1" data-descript="Quality women's tops made with authentic wool."></my-products>
        <my-products data-img1="images/p2.jpg" data-title="Women's Skirts" data-price="$350.00" data-link="https://reactor-js.com/p2" data-descript="Quality Women's skirts shirts made to last."></my-products>
        <my-products data-img1="images/p3.jpg" data-title="Men's T-Shirts" data-price="$150.00" data-link="https://reactor-js.com/p3" data-descript="Strecth quality men's button shirts made to last."></my-products>

        <reactor-container>{my-products}</reactor-container>
        <reactor-vars>{title, price, descript}</reactor-vars>
        <reactor-links>{link}</reactor-links>
        <reactor-imgs>{img1}</reactor-imgs>

        <div class="reactor">
            <img src='{img1}'>
            <h4>{title}</h4>
            <p>{price}</p>
            <hr/>
            <p>{descript}</p>
            <button>Add To Cart</button>
            <a href="{link}">{link}</a>
        </div>
    </div> 
</div>
Enter fullscreen mode Exit fullscreen mode

In a method similar to react, my reactor framework applies the props values inside html elements that have the brackets notations {}, which are passed as props from the html parameters above.

Ultimately, the framework achieves what react does with props.
Since then, i have added a routing feature, binding (like in angular), list-repeating, beaming (importing components) and some other useful features that i will talk about in a future post.

I've used this framework in numerous apps, you can have a look at the Reactor framework in action on this app:
www.flexrweb.com/showcaser
(The entire app uses reactor to display my portfolio apps and designs using props, routing, and beaming features).

The actual framework website can be viewed here:
https://reactor-js.com/

The cdn link to the framework is on the site as well. The website includes documentation on how to create an app with Reactor.

Direct CDN Link to add to your app/website:
https://reactor-js.com/reactor/reactorjs_2.4.2.js

Thanks for reading, the framework is open source and free to use, i would love to see what you build with it!

Top comments (0)