Replies: 3 comments 3 replies
-
Provide a hook to change the props of a component in an imperative manner, and centrally change the properties of the component to make the code more cohesive. |
Beta Was this translation helpful? Give feedback.
0 replies
-
import { isEmpty } from 'lodash-es';
import useUpdate from '../useUpdate';
import React, { forwardRef, isValidElement, useImperativeHandle, useRef } from 'react';
interface ComponentPropsInstance<Props> {
getProps(): Props;
setMergedProps(props: Partial<Props>);
setProps(props: Props);
}
const ProxyComponent = forwardRef((props: { children: React.ReactElement }, ref) => {
const { children } = props;
const update = useUpdate();
const memoryRef = useRef({
isValidElement: isValidElement(children),
children,
});
useImperativeHandle(
ref,
() => ({
getProps() {
return memoryRef.current.children.props;
},
setMergedProps(props) {
const isValidElement = memoryRef.current.isValidElement;
const beforeChildren = memoryRef.current.children;
if (isValidElement && !isEmpty(props)) {
const cloneChildren = React.cloneElement(beforeChildren, {
...beforeChildren.props,
...props,
});
memoryRef.current.children = cloneChildren;
update();
}
},
setProps(props) {
const isValidElement = memoryRef.current.isValidElement;
const beforeChildren = memoryRef.current.children;
if (isValidElement && !isEmpty(props)) {
const cloneChildren = React.cloneElement(beforeChildren, {
...props,
});
memoryRef.current.children = cloneChildren;
update();
}
},
}),
[],
);
return memoryRef.current.isValidElement ? memoryRef.current.children : null;
});
function useComponentProps<Props>(component: React.ReactElement<Props>) {
const memory = useRef({
componentProps: {} as ComponentPropsInstance<Props>,
component: (
<ProxyComponent
ref={(ref) => {
Object.assign(memory.current.componentProps, ref);
}}
>
{component}
</ProxyComponent>
),
});
return [
memory.current.componentProps,
memory.current.component as React.ReactElement<Props>,
] as const;
}
export default useComponentProps; |
Beta Was this translation helpful? Give feedback.
0 replies
-
Similar to: #2302, but more general. It's a good idea, Can you provide more examples of usage? thx |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Beta Was this translation helpful? Give feedback.
All reactions