clean-react-directives
Vue-like syntax for ReactJS CodeSandbox demo
Quick look
import React from 'react';import C from 'clean-react-directives'; const App = let number = 2; let paragraph = '<p>Hello world</p>' return <C> <div =>Number is divisible by 2</div> <div =>Number is my lucky number</div> <div >Number is number</div> <div = =></div> <div = /> </C> ;;
Installation
npm:
npm install clean-react-directives
yarn:
yarn add clean-react-directives
Table of contents
- Conditions: r-if, r-else-if, r-else
- r-show
- r-class
- r-html
- Lack of other directives: r-text, r-for and r-model
- Deep vs Shallow checking
- PERFORMANCE OPTIMIZATION
- Console hacking
Conditions: r-if, r-else-if, r-else
The directives r-if
, r-else-if
and r-else
are used to conditionally render a block they belong to. The block will only be rendered if the directive’s expression returns a truthy value.
Without clean-react-directives:
const App = let number = 2; let firstVisit = true; return <div> number % 2 === 0 ? <div>Number is divisible by 2</div> : number === 3 ? <div>Number is my lucky number</div> : number === 13 ? <div>This number is haunted</div> : <div>Number is number</div> !firstVisit && <div>Welcome back</div> </div> ;;
With clean-react-directives:
const App = let number = 2; let firstVisit = true; return <div> <C> <div =>Number is divisible by 2</div> <div =>Number is my lucky number</div> <div =>This number is haunted</div> <div >Number is number</div> <div =>Welcome back</div> </C> </div> ;;
r-show
Another option for conditionally displaying an element is the r-show
directive.
The difference is that an element with r-show
will always be rendered and remain in the DOM. r-show
only toggles the display CSS property of the element.
Without clean-react-directives:
const App = let inputVisible = false; return <div> <input ="text" =/> </div> ;;
With clean-react-directives:
const App = let inputVisible = false; return <div> <C> <input ="text" = /> </C> </div> ;;
r-class
clean-react-directives
uses classnames
npm package behind the scenes to provide joining classNames together. Example bellow is inspired with the examples from the classnames documentation.
Without clean-react-directives:
const App = let foo = 'foo-bar'; return <div> <div =></div> <div =></div> </div> ;;
With clean-react-directives:
const App = let foo = 'foo-bar'; return <div> <C> <div =></div> <div =></div> </C> </div> ;;
r-class
can be also used in the combination with the standard className directive:
const App = return <div> <C> <div ="item" =></div> </C> </div> ;;
r-html
Without clean-react-directives:
const App = let paragraph = '<p>Hello world</p>'; return <div> <div =></div> </div> ;;
With clean-react-directives:
const App = let paragraph = '<p>Hello world</p>' return <div> <C> <div =></div> </C> </div> ;;
Lack of other directives: r-text, r-for and r-model
The result of r-text
directive can easily be reproduced with the example bellow, therefore there is no need for additional directive.
const App = let text = 'Hello world' return <div>text</div>;;
Implementation of the r-for
and r-model
directives would require the use of the custom Babel plugin. Because of this, adding the library to your project would be much more difficult.
Current implementation only requires you to install one React component, which can be used anywhere in your app without unnecessary configuration.
Deep vs Shallow checking
There are two possible ways to use directive checking with clean-react-directives
, deep and shallow.
Shallow implementation would only check the direct children of the C
component:
const App = return <C> /* This scope is checked*/ <div =>Hello</div> <div > /* This scope is not checked*/ <h1 =>World</h1> </div> <div ="inner"> /* This scope is not checked*/ <div =>Foo</div> <div >Bar</div> </div> </C> ;;
Adding deep
flag to the C
component would check all descendant components:
const App = return /* All nested scopes are checked */ <C > <div =>Hello</div> <div > <h1 =>World</h1> </div> <div ="inner"> <div =>Foo</div> <div >Bar</div> </div> </C> ;;
PERFORMANCE OPTIMIZATION
For performance purposes, always keep the C
component as close to the components which have directives applied.
Less optimized way:
const App = return <div> <C > <div =>Hello</div> <div >World</div> <div =>Foo</div> <div ="wrapper"> <div ="level_1"> <div =>React is awesome</div> <div ="level_2"> <div =>Bar</div> <div =>Baz</div> </div> </div> </div> </C> </div> ;;
Better optimized way:
const App = return <div> <C> <div =>Hello</div> <div >World</div> <div =>Foo</div> </C> <div ="wrapper"> <div ="level_1"> <C > <div =>React is awesome</div> <div ="level_2"> <div =>Bar</div> <div =>Baz</div> </div> </C> </div> </div> </div> ;;
Console hacking
In the create-react-app in DEVELOPMENT mode, when passing a prop in the format prop-name
the react component, React expects the value of that prop to be a string.
Since we are passing non-boolean values to the directives r-if, r-else-if, r-else, and r-show, React will throw an error ( Received true
for a non-boolean attribute r-if
).
For this reason, we need to ignore the thrown error message if it is related to our library.
This is not ass clean as we would like it to be, but unfortunately, it is the only solution we have at this point.