I'm using a library in React, which implements a provider using the legacy context API.
This is the implementation:
import { Component, Children } from "react";
import PropTypes from "prop-types";
import Registry from "./registry";
class ConduitProvider extends Component {
constructor(props) {
super(props);
const { registry } = this.props;
this.registry = registry ? registry : new Registry();
}
getChildContext() {
return { registry: this.registry };
}
render() {
return Children.only(this.props.children);
}
}
ConduitProvider.childContextTypes = {
registry: PropTypes.object.isRequired,
};
export default ConduitProvider;
Is there a way to transform the provider into the context you would get with the nowadays context hook in React? The one you'd get by using
const MyContext = React.createContext(defaultValue);
I have a component which requires to forward all the contexts used inside and I'm trying to use a different component inside which uses the library.
I already tried wrapping the contents of the component in the Provider
, but that would not work as the component requires the context.
I also tried to create the context in numerous ways. The most optimistic one was creating a new provider using the Registry
from the library, but I could not make it work.
Edit: I didn't realize by transform you didn't mean the code, but instead consume and re-provide. In theory you would just do the below, but your ConduitProvider
would take the legacy context
argument as well. Normally it would be a better idea to fork and upgrade the library so you aren't tied to an outdated version of React, but since this feature is native to React (Portals) you don't need a library at all.
There isn't much to rewrite for the context itself, but you do have to update all of your children to consume context in the modern way (useContext
ideally).
export const ConduitContext = React.createContext({})
export const ConduitProvider = ({ registry, ...rest }) => {
const [registry, setRegistry] = useState(registry || new Registry())
return (
<ConduitContext.Provider value={registry} {...rest} />
)
}
export const useRegistry = () => React.useContext(RegistryContext)
You would then wrap your components with the provider component:
() => (
<ConduitProvider registry={someValueIfAvailable}>
{/* Your components */}
</ConduitProvider>
)
Your components would then do something like this:
const Foo = () => {
const registry = useRegistry()
// ...
}