Home > Back-end >  React Native - Require Cycle
React Native - Require Cycle

Time:11-20

What im facing:

I have a small RN project and, after implementing some basic logic for global state management, i've gotten this error when I start/restart my project:

Require cycle: App.js -> src\navigation.js -> src\components\Drawer.js -> App.js

Require cycles are allowed, but can result in uninitialized values. 
Consider refactoring to remove the need for a cycle.
//Error route info

Require cycle: App.js -> src\navigation.js -> src\pages\signIn.js -> App.js

Require cycles are allowed, but can result in uninitialized values. 
Consider refactoring to remove the need for a cycle.
//Error route info

Require cycle: App.js -> src\navigation.js -> App.js

Require cycles are allowed, but can result in uninitialized values. 
Consider refactoring to remove the need for a cycle.
//Error route info

I wrote my code based on this guide from React Navigation docs with some minor changes, it works as expected with the conditional rendering and all, but I keep getting this annoying error and I truly want to get rid of it.

My code:

App.js

//Useless imports
import Navigator from './src/navigation';
import appReducer from './src/reducers';

export const AuthContext = createContext();

const App = () => {
  const [state, dispatch] = useReducer(appReducer, initialStates);

  //useEffect to fetch stored credentials and change initialStates
  //for conditional rendering purposes
 
  return (
    <AuthContext.Provider value={[state, dispatch]}>
      <Navigator/>
    </AuthContext.Provider>
  );
}

export default App;

navigation.js

//Useless imports
import { AuthContext } from '../App';
import SignIn from './pages/SignIn';
import Drawer from './components/Drawer'; //Used in my Drawer Navigator declaration,
                                          //but I'll abstract some of my nav logic

export const Navigator = () => {
  const [state, dispatch] = useContext(AuthContext);

  return (
    <NavigationContainer>
      {
        state.someState ?
          <Screen1 component={SignIn} />
          :
          <Screen2 component={Screen2} />
      }
    </NavigationContainer>
  );
}

Drawer

///Useless imports
import { AuthContext }  from '../../App';

export const Drawer = () => {
  const [state, dispatch] = useContext(AuthContext);

  return (
    <Drawer>
      <Button onPress={() => dispatch({type: 'SIGN_OUT'})}/>
    </Drawer>
  );
}

SignIn.js

//Useless imports
import { AuthContext } from '../../App';

export const SignIn = () => {
  const [state, dispatch] = useContext(AuthContext);

  return (
    <View>
      <Button onPress={() => dispatch({type: 'SIGN_IN'})/>
    </View>
  );
}

I really don't think there's a problem with my reducer declaration or any stuff like that, because as I said before, the conditional rendering works as expected, and when I comment the AuthContext imports from the components or pages the warning is gone.

For information purposes, here is my folder structure:

My-App/
├── src/
│   ├── components/
│   │   └── Drawer.js
│   ├── pages/
│   │   └── SignIn.js
│   ├── reducers/
│   │   └── appReducer.js
│   └── navigation.js
└── App.js

CodePudding user response:

The warning is correct; since you're exporting AuthContext from App, and importing it in a component nested component, you have created a cycle. The easiest way around this is to move your authContext to a separate file that is imported by your App and SignIn pages.

  • Related