Trouble Shooting

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:

  1. The component has required props that do not have default values.
  2. 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>
  );
};