Git Product home page Git Product logo

fre's Introduction

fre logo

Fre

👻 Tiny React16 like library with Async rendering.

Build Status Code Coverage npm-v npm-d gzip

Feature

  • 🎉 Functional Component and hooks API
  • 🎊 Async rendering like react Fiber(also called time slicing, concurrent mode)
  • 🔭 keyed reconcilation(also called diff) algorithm

Introduction

Fre (pronounced /fri:/, like free) is a tiny and perfect js library, It means Free! ~

Package Version About
Fre npm fre core
Fard npm mini-program with fre
use-routes npm router for fre

Demo

Thanks for Rasmus Schultz

Use

yarn add fre
import { h, render, useState } from "fre"

function Counter() {
  const [count, setCount] = useState(0)
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

render(<Counter />, document.getElementById("root"))

Hooks API

useState

useState is a base API, It will receive initial state and return a Array

You can use it many times, new state is available when component is rerender

function Counter() {
  const [up, setUp] = useState(0)
  const [down, setDown] = useState(0)
  return (
    <div>
      <h1>{up}</h1>
      <button onClick={() => setUp(up + 1)}>+</button>
      <h1>{down}</h1>
      <button onClick={() => setDown(down - 1)}>-</button>
    </div>
  )
}

render(<Counter />, document.getElementById("root"))

useReducer

useReducer and useState are almost the same,but useReducer needs a global reducer

function reducer(state, action) {
  switch (action.type) {
    case "up":
      return { count: state.count + 1 }
    case "down":
      return { count: state.count - 1 }
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 1 })
  return (
    <div>
      {state.count}
      <button onClick={() => dispatch({ type: "up" })}>+</button>
      <button onClick={() => dispatch({ type: "down" })}>+</button>
    </div>
  )
}

render(<Counter />, document.getElementById("root"))

useEffect

useEffect takes two parameters, the first is a effect callback and the second is an array

if the array changed, the callback will execute after commitWork, such as pureComponentDidUpdate

if the array is empty, it means execute once, such as componentDidMount

if no array, it means execute every time , such as componentDidUpdate

if useEffect returns a function, the function will execute before next commitWork, such as componentWillUnmount

function Counter({ flag }) {
  const [count, setCount] = useState(0)
  useEffect(() => {
    document.title = "count is " + count
  }, [flag])
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

render(<Counter />, document.getElementById("root"))

useCallback

useCallback has the same parameters as useEffect, but useCallback will return a cached function.

const set = new Set()

function Counter() {
  const [count, setCount] = useState(0)
  const cb = useCallback(() => {
    console.log("cb was cached")
  }, [count])
  set.add(cb)

  return (
    <div>
      <h1>{set.size}</h1>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

useMemo

useMemo has the same parameters as useEffect, but useMemo will return a cached value.

function Counter() {
  const [count, setCount] = useState(0)
  const val = useMemo(() => {
    return new Date()
  }, [count])
  return (
    <div>
      <h1>
        {count} - {val}
      </h1>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

render(<Counter />, document.getElementById("root"))

useRef

useRef will return a object which contains current node.

import { useRef, useEffect } from "fre"

function Counter() {
  useEffect(() => {
    console.log(t) // { current:<div>t</div> }
  })
  const t = useRef(null)
  return <div ref={t}>t</div>
}

render(<Counter />, document.getElementById("root"))

FunctionalComponent

functionalComponent is a new components scheme

function App() {
  const [count, setCount] = useState(0)
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>+</button>
      <Sex count={count} />
    </div>
  )
}

function Sex(props) {
  const [sex, setSex] = useState("boy")
  return (
    <div>
      <h2>{props.count}</h2>
      <h1>{sex}</h1>
      <button
        onClick={() => {
          sex === "boy" ? setSex("girl") : setSex("boy")
        }}
      >
        x
      </button>
    </div>
  )
}

render(<App />, document.getElementById("root"))

props

Props are used for component communication

function App() {
  const [sex, setSex] = useState("boy")
  return (
    <div>
      <Sex sex={sex} />
      <button onClick={() => (sex === "boy" ? setSex("girl") : setSex("boy"))} />
    </div>
  )
}
function Sex(props) {
  return <div>{props.sex}</div>
}

Props contains children to render all the child elements of itself

const HelloBox = () => (
  <Box>
    <h1>Hello world !</h1>
  </Box>
)

const Box = props => <div>{props.children}</div>

Hooks do not support HOC and extends, but render props are supported by default

const HelloBox = () => <Box render={value => <h1>{value}</h1>} />

const Box = props => <div>{props.render("hello world!")}</div>

Also can be render children

const HelloBox = () => (
  <Box>
    {value => {
      return <h1>{value}</h1>
    }}
  </Box>
)

const Box = props => <div>{props.children("hello world!")}</div>

options

If you want to rewrite any function, please use options, such as:

options.end = false
options.commitWork = fiber => {
  // something you will rewrite commitWork
}

JSX

The default export h function needs to be configured

import { h } from "fre"
{
  "plugins": [["transform-react-jsx", { "pragma": "h" }]]
}

If browser environment, recommend to use htm

Async rendering

Fre implements a tiny priority scheduler, which like react Fiber.

Async rendering is also called time slicing or concurrent mode.

key-based reconcilation

Fre implements a compact reconcilation algorithm support keyed, which also called diff.

It uses hash to mark locations to reduce much size.

License

MIT ©132yse inspired by react anu

fre's People

Contributors

yisar avatar mindplay-dk avatar malash avatar yiliang114 avatar zhenhe17 avatar iosh avatar dependabot[bot] avatar duhongjun avatar

Watchers

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