Skip to content

sibbng/reactivue

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

23 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

{WIP} Use Vue Composition API in React components

npm i reactivue

I love Vue Composition API and its reactivity system,
but functional components in React are also sweet with Typescript.
Instead of making a choice, why not to use them together?


Usage

It's currently expiremental and might have some breaking changes in the future. No production yet but feel free to try it out.

Component Factory

import React from 'React'
import { defineComponent, ref, computed, onUnmounted } from 'reactivue'

interface Props {
  value: number
}

const MyCounter = defineComponent(
  // setup function in Vue
  (props: Props) => {
    const counter = ref(props.value)
    const doubled = computed(() => counter.value * 2)
    const inc = () => counter.value += 1

    onUnmounted(() => console.log('Goodbye World'))

    return { counter, doubled, inc }
  },
  // functional component in React
  ({ counter, doubled, inc }) => {
    // you can still use other React hooks
    return (
      <div>
        <div>{counter} x 2 = {doubled}</div>
        <button>Increase</button>
      </div>
    )
  }
)

// use it as you normally would
render(<MyCounter value={10}>, el)

Hooks

You can use it as a hook as well.

The defineComponent factory is actually a sugar to and equivalent to the following code.

import React from 'React'
import { useSetup, ref, computed, onUnmounted } from 'reactivue'

interface Props {
  value: number
}

function MyCounter(Props: Props) {
  const state = useSetup(
    (props: Props) => { // props is a reactive object in Vue
      const counter = ref(props.value)
      const doubled = computed(() => counter.value * 2)
      const inc = () => counter.value += 1

      onUnmounted(() => console.log('Goodbye World'))

      return { counter, doubled, inc }
    },
    Props // pass React props to it
  )

  // state is a plain object just like React state
  const { counter, doubled, inc } = state

  return (
    <div>
      <div>{counter} x 2 = {doubled}</div>
      <button>Increase</button>
    </div>
  )
}

APIs

Some tips and cavert compare to Vue's Composition API.

Reactivity

The reactivity system APIs are direct re-exported from @vue/reactivity, they should work the same as in Vue.

// the following two line are equivalent.
import { ref, reactive, computed } from 'reactivue'
import { ref, reactive, computed } from '@vue/reactivity'

Lifecycles

This library implemented the basic lifecycles to bound with React's lifecycles. For some lifecycles that don't have the React equivalent, they will be called somewhere near when they should be called (for example onMounted will be call right after onCreated).

For most of the time, you can use them like you would in Vue.

Extra APIs

  • defineComponent() - not the one you expected to see in Vue. Instead, it accepts a setup function and a render function that will return a React Functional Component.
  • useSetup() - the hook for resolve Composition API's setup, refer to the section above.

Limitations

  • No getCurrentInstance() - since we don't actually have a Vue instance here
  • emit() is not available

Example

Check example-vite

License

MIT - Anthony Fu 2020

About

๐Ÿ™Š Use Vue Composition API in React components

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 93.6%
  • JavaScript 3.2%
  • HTML 3.2%