how to convert my code to a sharable component

Viewed 172

I've a component that uses Redux, Redux-Sage and I want to convert it to a sharable library.

How can I structure my code and what to export to make it easier to share?

4 Answers

Ideally we should create stateless component for shareable library. But your components are appearing lots of dependency or state management constraint like Redux, Redux-saga etc. My suggestion, you should avoid this.

If you really want to do this then please create some initialization library function and enforce the calling of this function. The function should check for all pre-requiste before showing your component. But that will be challenging in term of coding.

Usually I would just export the different constituents of the "library" like this, and offer a guide how to integrate them into the projects redux... Long story short it would be... messy. But I'd do it like this:

const defaultState = {};

export libReducer = ( /* ... */ ) {
  //... 
}

export libSaga = ( /* ... */ ) {
  //... 
}

export LibComponent = ()=> {
  // ...
}

The problematic parts are redux and redux-saga though. Because it will be required to integrate the reducer using combineReducers, and the saga inside the applyMiddleware part during redux store integration.

import {
  createStore,
  applyMiddleware,
  combineReducers
} from 'redux';

import createSagaMiddleware from 'redux-saga';

// explain that this needs to be imported
import { libSaga, libReducer } from 'your-lib';

const sagaMiddleware = createSagaMiddleware()

// explain how to:
//  create a rootSaga to use multiple sagas
//  the equivalent of a combineReducers
//  but only IF the target project uses
//  saga at applyMiddleware. Else it would
//  be sufficient to:
//    sagaMiddleware.run(libSaga)
//  later...

function* rootSaga () {
    yield [
        fork(libSaga),
        fork(otherSagaThatProjectUses)
    ];
}

// explain howto use combineReducers
// and applyMiddleware to add your reducer
// and enable saga... again depending upon
// the project using redux/saga or not...

const store = createStore(
  combineReducers{
    // ...
    fixedNamespaceForYourLib: libReducer
  },
  applyMiddleware(sagaMiddleware)
)

sagaMiddleware.run(rootSaga);

The best practice is encapsulating your redux provider to use in all project (even non-redux based projects):

<Provider store={store}>
  <YourLibrary />
</Provider >

Frankly speaking, It is a really wide-open question. It'll significantly help to answer if you provide a code example or narrow down the context.

In general, it is preferable to avoid any other than React dependencies in a component as it would unlock it for projects without redux + redux saga stack. Often, state handling can be moved from Redux to the local component state, side-effects can be abstracted out. So it's boiling down the pure "view" component which gives enough flexibility for users to bind to custom business logic.

Here are a few general questions to consider regarding creating reusable lib:

  • What is the component actually supposed to do?
  • Is the component interface intuitive and unambiguous?
  • Can it be broken down into smaller and simpler components under the hood?
  • Does it have a good test coverage? Getting to a good test coverage will encourage having a well-structured and written set of components in a library.
Related