@bloc-arch/react
TypeScript icon, indicating that this package has built-in type declarations

1.2.1 • Public • Published

@bloc-arch/react

https://travis-ci.com/kasperski95/bloc-arch--react.svg?branch=master

Package provides hooks and components for BLoC architecture in React.

Table of Contents


Related packages

Setup and Usage Example (TypeScript)

// src/index.tsx
// ...
import { BlocProvider } from './blocs/setup-blocs'

ReactDOM.render(
  <React.StrictMode>
    <BlocProvider> {/* <= */}
      <App />
    </BlocProvider>
  </React.StrictMode>,
  document.getElementById('root')
)
// src/blocs/setup-blocs.ts
// ...
import { setupBlocs } from '@bloc-arch/react'

export const { BlocProvider, useWeakBloc, useBloc } = setupBlocs({
  sample: (dependency: any) => new SampleBloc(dependency),
  // ...
})
// src/blocs/sample/SampleBloc.ts
// (generated by @bloc-arch/cli)

import { Bloc } from '@bloc-arch/core'
import * as SampleEvents from './SampleEvent'
import * as SampleStates from './SampleState'

export class SampleBloc extends Bloc<
  SampleEvents.SampleEvent,
  SampleStates.SampleState
> {
  constructor() {
    super(new SampleStates.Initial())
  }

  async *mapEventToState(event: SampleEvents.SampleEvent) {
    // if (event instanceof SampleEvents.Foo) {
      yield new SampleStates.Loading()
      await new Promise((resolve) => setTimeout(resolve, 2000)) // wait 2s
      yield new SampleStates.NotInitial()
    /* 
    } else if (event instanceof SampleEvents.Bar) {
      ...
    }
    */
  }
}
// src/App.tsx
// ...
import { BlocBuilder, useBlocRenderProp } from '@bloc-arch/react'
import { useBloc } from './blocs/setup-blocs'

function App() {
  const sampleBloc = useBloc('sample')('dependency')

  return (
    <>
      <button
        onClick={() => {
          sampleBloc.dispatch(new SampleEvents.Foo())
        }}
      >
        click
      </button>
      <BlocBuilder
        bloc={sampleBloc}
        renderer={useBlocRenderProp((state) => {
          if (state instanceof SampleStates.Loading) {
            return <div>loading state</div>
          } else if (state instanceof SampleStates.NotInitial) {
            return <div>not initial state</div>
          }
          return <div>initial state</div>
        }, [])}
      />
    </>
  )
}

Docs

setupBloc

Takes as an argument object with functions creating blocs and returns BlocProvider, useBloc and useWeakBloc.

// setup blocs:
const { BlocProvider, useBloc, useWeakBloc } = setupBlocs({
  sample: () => new SampleBloc()
})

useBloc

Returns a function to instantiate bloc. Bloc is created only if it doesn't exist. Disposes bloc on component unmount.

// setup blocs:
export const { BlocProvider, useBloc } = setupBlocs({
  //...
  sample: () => new SampleBloc(),
})

// component:
const bloc = useBloc("sample")()

useWeakBloc

Returns a function to get a specified bloc if is available. Bloc is available between the time of creation and disposal.

// component:
const getSampleBloc = useWeakBloc("sample")
// ...
const handleClick = React.useCallback(() => {
  getSampleBloc()?.dispatch(new SampleEvents.Foo())
}, [getSampleBloc])

BlocProvider

Provider of blocs. Use property blocFactories to provide mocked blocks in case of testing.

// root component:
<BlocProvider blocFactories={{ sample: (dependency: any) => new SampleBlocMock() }}>
...
</BlocProvider>

BlocBuilder, useBlocRenderProp

BlocBuilder subscribes to bloc and maps states to views by the use of property renderer. Property listener is optional. Use it to react on state changes.

"useBlocRenderProp" is a pretty much a React.useCallback with ability to deduce type of state (TypeScript).

// component:
<BlocBuilder
  bloc={sampleBloc}
  listener={React.useCallback((state: SampleStates.SampleState) => {
    if (state instanceof SampleStates.NotInitial) {
      props.callback()
    }
  }, [props.callback])}
  renderer={useBlocRenderProp((state) => {
    if (state instanceof SampleStates.Loading) {
      return <div>loading state</div>
    } else if (state instanceof SampleStates.NotInitial) {
      return <div>not initial state</div>
    } else {
      return <div>{props.someProp}</div>
    }
  }, [props.someProp])}
/>

Readme

Keywords

Package Sidebar

Install

npm i @bloc-arch/react

Weekly Downloads

6

Version

1.2.1

License

MIT

Unpacked Size

13.3 kB

Total Files

11

Last publish

Collaborators

  • kasperski95