Trouble Shooting
This page deals with common issues that may arise because of the isolated component rendering by Visualwind.
My Component is NOT Rendering
Apart from you code being erroneous, there are typically two reasons why a component may not render:
- The component has required props that do not have default values.
- The component has hooks that requires provider, but you didn't set
visualwind.wrapper.tsx
to provide the required provider.
These are ultimitely caused because the component is not being rendered in the context of a parent component, but rather in isolation. Let's take a look at each of these issues:
1. Required Props
Let's say you have a component that renders a list of names in a school class:
import React from 'react';
export function NameList({ names }: { names: string[] }) {
return (
<>
{names.map((name, index) => (
<div key={index}>{name.toString()}</div>
))}
</>
);
}
Visualwind tries to render this component in isolation, which means it is kinda like running the following code:
import React from 'react';
export const VisualwindApp = () => {
return <NameList />;
};
(More precisely, it's actually more like rendering <Wapper><NameList /></Wrapper>
, not <NameList>
.)
The above code will throw an error, because NameList
requires a prop names
that is not provided. When the code tries to access names.map
, it will throw an error because names
is not an array, but undefined
.
So how do we fix this? The simplest way to fix this is to provide a default value for names
:
import React from 'react';
// note that we provide a default value for names, ['Alice', 'Bob', 'Charlie'].
export const NameList = ({ names = ['Alice', 'Bob', 'Charlie'] }: { names: string[] }) => {
return (
<ul>
{names.map((name, index) => (
<li key={index}>{name}</li>
))}
</ul>
);
};
While this is not always applicable, about 90% of the time, this is the easiest way to fix the issue.
2. Hooks that Requires Provider
Some hooks require a provider to be set in the parent component. For example, useQuery
from react-query
requires a QueryClientProvider
to be set in the parent component.
//nameList.tsx
import React from 'react';
import { useQuery } from 'react-query';
export const NameList = () => {
const { data } = useQuery('names', async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
return response.json();
});
return (
<ul>
{data.map((name, index) => (
<li key={index}>{name}</li>
))}
</ul>
);
};
To make this work, you probably wrapped the entire app in a QueryClientProvider
in your App.tsx
:
// App.tsx
import React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { NameList } from './NameList';
const queryClient = new QueryClient();
const App = () => {
return (
<QueryClientProvider client={queryClient}>
<NameList />
</QueryClientProvider>
);
};
export default App;
//nameList.tsx
import React from 'react';
import { useQuery } from 'react-query';
export const NameList = () => {
const { data } = useQuery('names', async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
return response.json();
});
return (
<ul>
{data.map((name, index) => (
<li key={index}>{name}</li>
))}
</ul>
);
};
export default NameList;
However, when you try to render NameList
in isolation within Visualwind, it will throw an error because <NameList>
is now NOT wrapped in a QueryClientProvider
.
So how do we fix this? This is where visualwind.wrapper.tsx
comes in. As we briefly mentioned, all your components are rendered within a <Wrapper>
component that you define in visualwind.wrapper.tsx
. This is where you can provide the QueryClientProvider
:
// visualwind.wrapper.tsx
import React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
const queryClient = new QueryClient();
export const Wrapper: React.FC = ({ children }) => {
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>;
};
Now, when you render NameList
in Visualwind, it will be wrapped in a QueryClientProvider
and the error will be resolved. In other words, Visualwind will render:
//Visualwind renders this
import React from 'react';
import Wrapper from '@/visualwind.wrapper.tsx';
import NameList from '@/nameList.tsx';
export const VisualwindApp = () => {
return (
<Wrapper /* QueryClientProvider is provided here */>
<NameList />
</Wrapper>
);
};