Skip to content

Commit aa9c885

Browse files
committed
Improve troubleshooting section
1 parent f4b4609 commit aa9c885

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

versioned_docs/version-5.x/troubleshooting.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,104 @@ YellowBox.ignoreWarnings([
158158
]);
159159
```
160160
161+
## I'm getting "Invalid hook call. Hooks can only be called inside of the body of a function component"
162+
163+
This can happen when you pass a React component to an option that accepts a function returning a react element. For example, the [`header` option in stack navigator](stack-navigator.md#header) expects a function returning a react element:
164+
165+
```js
166+
<Stack.Screen
167+
name="Home"
168+
component={Home}
169+
option={{ header: (props) => <MyHeader {...props} /> }}
170+
/>
171+
```
172+
173+
If you directly pass a function here, you'll get this error when using hooks:
174+
175+
```js
176+
<Stack.Screen
177+
name="Home"
178+
component={Home}
179+
option={{
180+
// This is not correct
181+
header: MyHeader,
182+
}}
183+
/>
184+
```
185+
186+
The same applies to other options like `headerLeft`, `headerRight`, `tabBarIcon` etc. as well as props such as `tabBar`, `drawerContent` etc.
187+
188+
## Screens are unmounting/remounting during navigation
189+
190+
Sometimes you might have noticed that your screens unmount/remount, or your local component state or the navigation state resets when you navigate. This might happen if you are creating React components during render.
191+
192+
The simplest example is something like following:
193+
194+
```js
195+
function App() {
196+
return (
197+
<Stack.Navigator>
198+
<Stack.Screen
199+
name="Home"
200+
component={() => {
201+
return <SomeComponent />;
202+
}}
203+
/>
204+
</Stack.Navigator>
205+
);
206+
}
207+
```
208+
209+
The `component` prop expects a React Component, but in the example, it's getting a function returning an React Element. While superficially a component and a function returning a React Element look the exact same, they don't behave the same way when used.
210+
211+
Here, every time the component re-renders, a new function will be created and passed to the `component` prop. React will see a new component and unmount the previous component before rendering the new one. This will cause any local state in the old component to be lost. React Navigation will detect and warn for this specific case but there can be other ways you might be creating components during render which it can't detect.
212+
213+
Another easy to identify example of this is when you create a component inside another component:
214+
215+
```js
216+
function App() {
217+
const Home = () => {
218+
return <SomeComponent />;
219+
};
220+
221+
return (
222+
<Stack.Navigator>
223+
<Stack.Screen name="Home" component={Home} />
224+
</Stack.Navigator>
225+
);
226+
}
227+
```
228+
229+
Or when you use a higher order component (such as `connect` from Redux, or `withX` functions that accept a component) inside another component:
230+
231+
```js
232+
function App() {
233+
return (
234+
<Stack.Navigator>
235+
<Stack.Screen name="Home" component={withSomeData(Home)} />
236+
</Stack.Navigator>
237+
);
238+
}
239+
```
240+
241+
If you're unsure, it's always best to make sure that the components you are using as screens are defined outside of a React component. They could be defined in another file and imported, or defined at the top level scope in the same file:
242+
243+
```js
244+
const Home = () => {
245+
return <SomeComponent />;
246+
};
247+
248+
function App() {
249+
return (
250+
<Stack.Navigator>
251+
<Stack.Screen name="Home" component={Home} />
252+
</Stack.Navigator>
253+
);
254+
}
255+
```
256+
257+
This is not React Navigation specific, but related to React in general. You should always avoid creating components during render, whether you are using React Navigation or not.
258+
161259
## App is not working properly when connected to Chrome Debugger
162260
163261
When the app is connected to Chrome Debugger (or other tools that use Chrome Debugger such as [React Native Debugger](https://github.com/jhen0409/react-native-debugger)) you might encounter various issues related to timing.

0 commit comments

Comments
 (0)