{"id":11898,"library":"react-universal-interface","title":"React Universal Interface for Component Patterns","description":"React Universal Interface (react-universal-interface) is a lightweight utility library designed to simplify the creation of React components that can be consumed via multiple popular patterns, including Function-as-a-Child (FaCC), render props, component props, and Higher-Order Components (HOCs). It offers two primary functions: `render` for processing various child/prop definitions within a component's render method, and `createEnhancer` for generating HOCs. The package's current stable version is 0.6.2, released in May 2020. Given the lack of updates since then, the project appears to be abandoned, with no active release cadence. Its key differentiator was providing a unified API to handle diverse component interaction paradigms, a common challenge in the evolving React ecosystem before Hooks became the dominant approach for logic reuse.","status":"abandoned","version":"0.6.2","language":"javascript","source_language":"en","source_url":"https://github.com/streamich/react-universal-interface","tags":["javascript","react","universal","interface","children","definition","ucd","universal-children","facc","typescript"],"install":[{"cmd":"npm install react-universal-interface","lang":"bash","label":"npm"},{"cmd":"yarn add react-universal-interface","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-universal-interface","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core library for building user interfaces with React components.","package":"react","optional":false},{"reason":"TypeScript runtime library, moved to peerDependencies in v0.6.2 for better dependency management.","package":"tslib","optional":false}],"imports":[{"note":"Primary function for handling universal children definition. While CommonJS `require` might work in some transpiled environments, ESM `import` is the idiomatic way for modern React projects.","wrong":"const { render } = require('react-universal-interface');","symbol":"render","correct":"import { render } from 'react-universal-interface';"},{"note":"Used to create Higher-Order Components from FaCC components. Follows the same import conventions as `render`.","wrong":"const createEnhancer = require('react-universal-interface').createEnhancer;","symbol":"createEnhancer","correct":"import { createEnhancer } from 'react-universal-interface';"},{"note":"TypeScript interface for extending component props to support the universal interface patterns. Only needed for TypeScript projects.","symbol":"UniversalProps","correct":"import { UniversalProps } from 'react-universal-interface';"}],"quickstart":{"code":"import React, { Component } from 'react';\nimport { render, createEnhancer, UniversalProps } from 'react-universal-interface';\n\ninterface MyDataState {\n  counter: number;\n}\n\ninterface MyDataProps extends UniversalProps<MyDataState> {}\n\nclass MyData extends Component<MyDataProps, MyDataState> {\n  state = { counter: 0 };\n\n  componentDidMount() {\n    this.interval = setInterval(() => {\n      this.setState(prevState => ({ counter: prevState.counter + 1 }));\n    }, 1000);\n  }\n\n  componentWillUnmount() {\n    clearInterval(this.interval);\n  }\n\n  interval: NodeJS.Timeout | undefined;\n\n  render() {\n    return render(this.props, this.state);\n  }\n}\n\nconst MyChildComponent: React.FC<MyDataState> = ({ counter }) => (\n  <div>Current counter: {counter}</div>\n);\n\n// Usage with Function-as-a-Child (FaCC)\nfunction App() {\n  return (\n    <div>\n      <h2>FaCC Example:</h2>\n      <MyData>{(state) => <MyChildComponent {...state} />}</MyData>\n\n      <h2>Render Prop Example:</h2>\n      <MyData render={(state) => <MyChildComponent {...state} />} />\n\n      <h2>Component Prop Example:</h2>\n      <MyData comp={MyChildComponent} />\n      <MyData component={MyChildComponent} />\n\n      <h2>Prop Injection Example:</h2>\n      <MyData>\n        <MyChildComponent />\n      </MyData>\n    </div>\n  );\n}\n\n// Example of Higher Order Component usage\nconst withCounter = createEnhancer(MyData, 'data');\nconst EnhancedChild = withCounter(MyChildComponent);\n\nfunction HOCApp() {\n    return (\n        <div>\n            <h2>HOC Example:</h2>\n            <EnhancedChild /> {/* MyChildComponent will receive 'data' prop from MyData */}\n        </div>\n    );\n}\n\nexport default App;","lang":"typescript","description":"Demonstrates the `MyData` component leveraging `render` to support FaCC, render prop, component prop, and prop injection patterns, alongside `createEnhancer` for HOCs."},"warnings":[{"fix":"Run `npm install tslib` or `yarn add tslib` in your project root.","message":"`tslib` was moved from a direct dependency to a peerDependency in version 0.6.2. If you are upgrading from a version prior to 0.6.2, you might need to manually install `tslib` in your project if you encounter build errors related to missing TypeScript helper functions.","severity":"breaking","affected_versions":">=0.6.2"},{"fix":"Exercise caution when using in new projects or upgrading React. Consider alternative patterns (like Hooks) for logic sharing, which are the modern idiomatic approach in React.","message":"This package appears to be abandoned, with the last release in May 2020. It is unlikely to receive updates for compatibility with newer React versions (e.g., React 17, 18, 19 and beyond) or address new issues. Functionality may break with future React updates.","severity":"gotcha","affected_versions":">=0.6.2"},{"fix":"For new feature development or refactoring, evaluate if React Hooks can achieve the desired state/logic sharing with less complexity.","message":"The patterns promoted (FaCC, render props, HOCs) are still valid but less commonly used for stateful logic sharing in modern React development, which largely favors Hooks. While this library unifies them, relying heavily on it might diverge from current best practices and introduce additional abstraction layers.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure `render` is called within a class component's method (e.g., `this.render()`) and `this.props` is correctly accessible. Use arrow functions for event handlers to preserve `this`.","cause":"Often occurs when `this` context is lost in a class component, or `render` is called outside a component's instance context.","error":"TypeError: Cannot read properties of undefined (reading 'props')"},{"fix":"Ensure your component's props interface extends `UniversalProps<TState>`, where `TState` is the type of data your component provides (e.g., `MyDataState` in the example). Verify that the data provided to children matches the expected type.","cause":"Incorrectly typing the component props when using TypeScript, not extending `UniversalProps` correctly, or passing unexpected children/props to the `MyData` component.","error":"TS2345: Argument of type '{ children: ({ counter }: { counter: number; }) => Element; }' is not assignable to parameter of type 'MyDataProps'."}],"ecosystem":"npm"}