renderProp.js 1.2 KB

12345678910111213141516171819202122232425262728
  1. import * as React from 'react';
  2. import { useState, useCallback, useEffect, useLayoutEffect } from 'react';
  3. export function renderCar(WrappedComponent, defaults) {
  4. function State({ stateRef, props }) {
  5. const renderTarget = useCallback(function SideTarget(...args) {
  6. useLayoutEffect(() => {
  7. stateRef.current(args);
  8. });
  9. return null;
  10. }, []);
  11. // @ts-ignore
  12. return React.createElement(WrappedComponent, { ...props, children: renderTarget });
  13. }
  14. const Children = React.memo(({ stateRef, defaultState, children }) => {
  15. const [state, setState] = useState(defaultState.current);
  16. useEffect(() => {
  17. stateRef.current = setState;
  18. }, []);
  19. return children(...state);
  20. }, () => true);
  21. return function Combiner(props) {
  22. const defaultState = React.useRef(defaults(props));
  23. const ref = React.useRef((state) => (defaultState.current = state));
  24. return (React.createElement(React.Fragment, null,
  25. React.createElement(State, { stateRef: ref, props: props }),
  26. React.createElement(Children, { stateRef: ref, defaultState: defaultState, children: props.children })));
  27. };
  28. }