jamiebuilds / unstated-next

200 bytes to never think about React state management libraries ever again
MIT License
4.18k stars 145 forks source link

Ideas for covering more use cases #87

Open namannehra opened 4 years ago

namannehra commented 4 years ago

Problems

I am using unstated-next in a project. I found some situations where I couldn't use unstated-next and had to write contexts, providers and hooks myself. These were caused by following limitation of unstated-next.

1. Only initial state

Only initial state can be passed to providers. This makes it impossible to use unstated-next in certain situations. Initial state can be easily implemented in the function passed to createContainer using useState. So I think providers should always pass the state directly.

2. Only one prop on provider

Providers only accepts one prop named initialState. Making this configurable will be helpful.

Possible solution

JS

import React, { useState } from 'react'
import { createContainer } from 'unstated-next'

const useTheme = options => {
    const [initialType] = useState(options.initialType)
    const { primaryColor } = options
    // ...
}

const ThemeContainer = createContainer(useTheme)

const App = () => {
    <ThemeContainer.Provider initialType="light" primaryColor="red"></ThemeContainer.Provider>
}

TS

import React, { useState } from 'react'
import { createContainer } from 'unstated-next'

interface UseThemeOptions {
    initialType: 'light' | 'dark'
    primaryColor: string
}

const useTheme = (options: UseThemeOptions) => {
    const [initialType] = useState(options.initialType)
    const { primaryColor } = options
    // ...
}

const ThemeContainer = createContainer(useTheme)

const App = () => {
    <ThemeContainer.Provider initialType="light" primaryColor="red"></ThemeContainer.Provider>
}

Notes

The type of the first argument can be used to determine the props of the provider. The provider can pass its props object directly to useContainer.

const createContainer = <T extends {}, U>(useContainer: (T) => U) => {
    type ProviderProps = T
    // ...
}
namannehra commented 4 years ago

@jamiebuilds Any thoughts on this?