Git Product home page Git Product logo

rct's Introduction

rct

Clojars Project

A library that helps you write modern React components in Clojurescript however you like.

As the layer between ClojureScript and React, rct aims to be minimal and powerful - it should introduce as little abstraction as possible to smooth the boundary and give the user as much control as possible to leverage that abstraction.

API

The rct.core API consists of two protocols, each with a single method:

  • ReactComponent
    • as-component
  • ReactElement
    • as-element

You can call the methods to conform data to a native React Component and React Element. You do this when providing components or elements to native code (for example, when rendering your root element to the DOM).

You can extend the protocols to use new data types as React Components, like CLJS maps for class-based components, and React Elements, like CLJS vectors for Hiccup-style templates (included!).

Note that you don't have to "adapt" native Components to use them - these ReactComponent implementations are already provided in the library.

Rationale

There are a handful of existing libraries for writing React components in Clojurescript, like Reagent, Rum, and Om. All of these provide features for defining React components using DSLs and managing reactive state. The closest relative of this library is probably hx - both hx and rct try to give the user the best tool for writing modern React components, and explicitly leave state management out of scope. The main differentiating factor for rct is that the API is smaller and more extensible, and thus more likely to compose well with the other tools you're working with.

Stateful Components

React 16.8 brought us Hooks, which let you access the all the rich state and lifecycle APIs from functional components. This greatly improves the ergonomics for developers looking to build stateful React apps in idiomatic ClojureScript. rct provides wrappers to some of these in rct.hooks.

Examples

Hello World

(ns rct.example.hello-world
    (:require ["react-dom" :as react-dom]
              [rct.core :refer [as-element]]))

(defn hello []
   [:p {:style {:color "blue"}} "Hello World"]) 

(react-dom/render
    (as-element [hello])
    (.-body js/document))

Function Component using Props

(defn function-component [{:keys [message]}]
   [:p {:style {:color "blue"}} message])

(react-dom/render
    (as-element [function-component {:message "Hi, Function Component!"}])
    (.-body js/document))

Stateful Component using React Hook

(ns rct.example.counter
    (:require ["react-dom" :as react-dom]
              [rct.core :refer [as-element]]
              [rct.hooks :refer [use-state]]))

(defn counter [{:keys [init]}]
  (let [[v set-v] (use-state init)]
      [:<>
       [:p {} (str "Count: " v)]
       [:button {:onClick #(-> v inc set-v)} "Click to Increment"]]))

(react-dom/render 
    (as-element [counter {:init 0}]) 
    (.-body js/document))

JS Component Interop (nothing special!)

(ns rct.example.interop
    (:require ["react-dom" :as react-dom]
              ["special-js-input-lib" :refer [SpecialJsInputComponent]]
              [rct.core :refer [as-element]]))

(defn user-input [{:keys [onSubmit]}]
  (let [[v set-v] (use-state init)]
      [:<>
       [SpecialJsInputComponent {:value v :onChange set-v}]
       [:button {:onClick #(onSubmit v)} "Submit"]]))

(react-dom/render 
    (as-element [user-input {:onSubmit js/alert}])
    (.-body js/document))

Feedback?

Feel free to send me questions and comments via email (see Github profile), DM on Clojurians (@anson), or post an issue :)

I think this could probably reach a very useful stable state with some more polish on the Hooks wrappers (hx has a lot of this) and a ReactComponent impl that lets you write class-based components as CLJS maps (I haven't needed this, but I'm sure some people do).

License

Copyright © 2020 Anson Rosenthal

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

rct's People

Contributors

anrosent avatar

Stargazers

Josef Pospíšil avatar Amin Abdul Manaf avatar Burin Choomnuan avatar Tom H. avatar Tomáš Horáček avatar Antonin Hildebrand avatar

Watchers

James Cloos avatar  avatar  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.