Skip to content

Commit

Permalink
fix: fix reavue rerendering diff ReactInVue (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
Debove Christopher authored Sep 3, 2022
1 parent 3df020e commit 0aaf686
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 12 deletions.
16 changes: 15 additions & 1 deletion src/wrappers/React.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ReactNode } from 'react';
import React from 'react';
import { render } from '@testing-library/vue';
import { fireEvent, render } from '@testing-library/vue';
import userEvent from '@testing-library/user-event';
import { ReactWrapper } from './React';
import { defineComponent } from '@vue/composition-api';
Expand Down Expand Up @@ -68,6 +68,20 @@ describe('Vue Wrapper', () => {
await findByText('Count is: 0');
});

it('Should not replace the entire element', async () => {
const { findByText, getByRole, debug } = render(VueCountComponentTester, {
props: {
component: ReactCountComponent,
},
});

const reactRoot = await findByText('Count is: 0');
await fireEvent.click(getByRole('button'));
const reactRootRerender = await findByText('Count is: 1');

expect(reactRootRerender).toBe(reactRoot);
});

it('should render the ReactComponent with props', async () => {
const { findByText } = render(ReactWrapper, {
props: {
Expand Down
24 changes: 15 additions & 9 deletions src/wrappers/React.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import { VueWrapper } from './Vue';

const wrapVueChildren = (children: any) => {
return defineComponent({
render: (createElement) => createElement('div', children),
render: (createElement) => children,
});
};

const makeReactComponent = (Component: ComponentType<{ children?: ReactNode }>) => {
const ReactComponent = function ({ children, ...props }: any) {
const wrappedChildren = wrapVueChildren(children);

return (
<Component {...props}>{children && <VueWrapper component={wrappedChildren} />}</Component>
<Component {...props}>
{children && <VueWrapper component={wrapVueChildren(children)} />}
</Component>
);
};

Expand All @@ -36,16 +36,17 @@ export const ReactWrapper = defineComponent({
data() {
return {
reactRoot: null,
} as { reactRoot: any };
Component: null,
} as { reactRoot: any; Component: any };
},
mounted() {
this.reactRoot = createRoot(this.$refs.react as HTMLDivElement);
this.Component = makeReactComponent(this.$props.component);
this.mountReactComponent(this.reactRoot);
},
methods: {
mountReactComponent(reactRoot: Root) {
const { component, passedProps } = this.$props;
const Component = makeReactComponent(component);
const { passedProps } = this.$props;
const children = this.$slots.default !== undefined ? { children: this.$slots.default } : {};

// Bind `@click` to `onClick`, `@submit` to `onSubmit`, ...
Expand All @@ -56,15 +57,20 @@ export const ReactWrapper = defineComponent({
])
);

reactRoot.render(<Component {...passedProps} {...children} {...this.$attrs} {...onEvents} />);
reactRoot.render(
<this.Component {...passedProps} {...children} {...this.$attrs} {...onEvents} />
);
},
},
updated() {
this.mountReactComponent(this.reactRoot);
},
watch: {
$props: {
handler() {
handler(newProps, oldProps) {
if (oldProps.component !== newProps.component) {
this.Component = makeReactComponent(newProps.component);
}
this.mountReactComponent(this.reactRoot);
},
deep: true,
Expand Down
11 changes: 9 additions & 2 deletions src/wrappers/Vue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,12 @@ export const VueWrapper = function VueWrapper<P>({
const vueInstance = useRef<Vue | null>(null);
const childrenRef = useRef<ReactNode | undefined>();
const listenersRef = useRef<Record<string, any> | undefined>(on);
const componentRef = useRef<any>(component);

useEffect(() => {
childrenRef.current = children;
listenersRef.current = on;
componentRef.current = component;

if (vueInstance.current) {
Object.assign(vueInstance.current.$data, props);
Expand All @@ -69,6 +71,7 @@ export const VueWrapper = function VueWrapper<P>({

useEffect(() => {
const el = rootEl.current;
componentRef.current = component;

if (el) {
const instance = (vueInstance.current = new Vue({
Expand All @@ -78,7 +81,7 @@ export const VueWrapper = function VueWrapper<P>({
render(createElement) {
return createElement('div', { directives: [{ name: 'vue-element' }] }, [
createElement(
VUE_COMPONENT_NAME,
componentRef.current,
{
props: this.$data,
on: listenersRef.current,
Expand All @@ -87,8 +90,12 @@ export const VueWrapper = function VueWrapper<P>({
),
]);
},
computed: {
Component() {
return componentRef.current;
},
},
components: {
[VUE_COMPONENT_NAME]: component,
'revue-internal-react-wrapper': ReactWrapper,
},
...$rootVariables,
Expand Down

0 comments on commit 0aaf686

Please sign in to comment.