NextJS React Context Sharing Across Libraries - reactjs

I have an App Package(APP) which is a Nextjs package. I'm using a custom library(LIB) inside this package.
APP package.json
'LIB':'some github package'
I'm trying to have a react context declared in LIB and used both on LIB and APP.
MainContext.js inside LIB
export const MainContext = createContext({
all: 'default value',
setAll: () => {},
});
_app.js inside APP
import { MainContext } from 'LIB'
....
function MyApp({ Component, pageProps }) {
const [all, setAll] = useState({})
return (
<MainContext.Provider value={{ all, setAll }}>
.....
</MainContext.Provider>
);
}
However, I'm facing issues such as TypeError: Cannot read properties of undefined (reading 'Provider')
I tried log the context many times, and it does exist and it is imported correctly, still, I'm stuck with errors that Provider is undefined.
At some point, I logged the provider and it existed then it disappears. I'm pretty sure something is wrong there but I can not find it.

Related

Monorepo with custom hooks throws: could not find react-redux context valuel please ensure the component is wrapped in a <Provider>

I have a monorepo React setup built using lerna tool where I have one package that is storing the Redux state and exports createStore method. There is also one custom hook:
import {useSelector} from 'react-redux';
export const useSignInEffect = (effect: EffectCallback) => {
const isSignedIn = useSelector((state: RootState) => state.auth.isSignedIn);
useEffect(() => {
if (isSignedIn) {
return effect();
}
}, [isSignedIn]);
};
Everything else works well, redux store besides this hook where I get the following error. Do I need to do something additional here?
This most commonly means that your build system is pulling in multiple copies of react or react-redux. Make sure that any "library"-type packages are set to use react and react-redux as peer dependencies, not full dependencies, and that only one copy of each is in your app bundle.

react-i18next:: You will need to pass in an i18next instance by using initReactI18next

react-i18next:: You will need to pass in an i18next instance by using initReactI18next
I recently added the package and got this error. I have followed all the steps as far as I know.
I use Next.js with the next-i18next package which usually initialises itself automatically.
https://github.com/m2vi/downloader
From the next-i18next docs:
Then we add serverSideTranslation to getStaticProps or getServerSideProps (depending on your case) in our page-level components.
Meaning you'll need to add serverSideTranslation to the pages that need translations.
For example in your pages/d/[tab]/index file:
import Head from 'next/head';
import { Input } from '../../../components/Input';
import YouTube from '../../../components/youtube/Main';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
const index = () => {
return (
<>
<Head>
<title>YouTube</title>
</Head>
<YouTube />
</>
);
};
export const getServerSideProps = async ({ locale }) => ({
props: {
...(await serverSideTranslations(locale, ['common']))
}
});
export default index;
Then further down in your Main component you can access the documentation translation using:
t('pages.documentation')
update next-i18next.config.js
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'de', 'fr'],
},
react: { useSuspense: false },//this line
};
I had this issue too.
But I had "revalidate" property in getStaticProps. When I removed it, the error went away.
P.S. Maybe this will help someone
This error message may be shown although it is not the root cause of the problem.
I had the following build error message:
react-i18next:: You will need to pass in an i18next instance by using initReactI18next
TypeError: Cannot read properties of undefined (reading 'split')
at LanguageSwitcherLink ...
The root cause here was the TypeError.
In my case, the TypeError occurred because I had components with parameters in pages directory. Thus, during next build these components were attempted to be build as static pages. This failed because expected parameters were missing, which is why they were undefined.
Solution for me: move components outside of pages folder.
Afterwards, there is also no error message anymore with respect to initReactI18next.

Invalid hook call expo

I am creating a monorepo to store both the web app and expo app for a project. I have setup using https://github.com/altick/cra-expo-monorepo . I have created a shared folder to store the common code.
I am facing an issue importing a react component which uses a hook into the expo app, it gives the following error
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
I also faced the same issue in the react web app, I found out it was due to multiple react copies( both in the app and the shared one) but I was able to solve it by updated the webpack config to use the apps react through webpack alias. However, I dont know how to achieve the same with expo.
An example component
import React,{useState} from "react";
export const Dummy = () => {
const [data, setData] = useState("Test");
return <>{data}</>
}
I want to know how can I solve this issue
You can't use React hook outside of main function. I am pretty sure you put const Dummy() function outside the main function.
import React,{useState} from "react";
export const Dummy = () => {
const [data, setData] = useState("Test");
return <>{data}</>
}
export default function SomeMainFunction() {
...
}
please change above function as below.
import React,{useState} from "react";
export default function SomeMainFunction() {
export const Dummy = () => {
const [data, setData] = useState("Test");
return <>{data}</>
}
...
}

How to mock a React Component in the __mocks__ directory with jest?

I have been trying to extract a common mocked component to the mocks folder without success. I am only able to do it with regular JS files, but not with Components.
If I have a module getList as so:
export const getBigger = (a, b) => {
return a >= b ? a : b;
};
I can use it inside my component as so:
export default function App() {
const bigger = getBigger("a", "b");
return (
<div className="App">
<Bigger bigger={bigger} />
</div>
);
}
And I can put the pure js function inside the mocks folder
export const getBigger = jest.fn((p1, p2) => false);
And I can import it in my test without any problems:
import { getBigger as mockedGetBigger } from '../utils';
jest.mock('../utils');
And do my assertions:
expect(mockedGetBigger).toHaveBeenCalledTimes(1);
expect(mockedGetBigger).toHaveBeenCalledWith('a', 'b');
But I can't do the same if I want to mock the Bigger Component, it only works as so:
jest.mock('../Bigger', () => ({
Bigger: jest.fn(() => <>Mocked Bigger Component</>),
}));
But if I extract the function to the mocks folder and I try to use it just as the simple js function I get an error:
import React from 'react';
export const Bigger = jest.fn(() => <>Mocked Bigger Image</>);
And in the test import it and use it as:
import { Bigger as MockedBigger } from '../Bigger';
jest.mock('../Bigger');
I get the following error:
Error: Uncaught [Error: Bigger(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.]
I am not sure what the difference is when jest is importing and mocking in the same step or going to look for the mock function to the mocks folder.
Any ideas?
Somebody else complained about it here: https://github.com/facebook/jest/issues/6935
I made a simple codesandbox to help to understand the problem: https://codesandbox.io/s/mocks-folder-example-oxht3?file=/src/index.js
And here is the guide from jest to put your mocks in the __mocks__ folder
In the end, I found out.
I created a CodeSandbox but as it happens, jest.mock() is not available in CodeSandbox yet...
Anyway my problem was that I was not using the same extension for the real file and its corresponding file in the __mocks__ folder.
Silliest mistake ever!

React Developer Tools shows all components as "Anonymous"

I've installed the React Developer Tools extension on Google Chrome to debug a React application written in TypeScript, but once I start debugging the application and open the "Components" window, all components are shown as "Anonymous".
Granted, the application uses mostly function components.
Does anyone know if there is a way to get React Developer Tools to show component names in its component tree?
This happens when you define your components like so:
// Default arrow function export
export default () => {
// ...
}
// Default function export
export default function() {
// ...
}
You can replace with the following to fix the issue:
const CustomComponent = () => {
// ...
}
export default CustomComponent;
// or
export default function YourComponent() {
// ...
}
If you're using an exported anonymous functional component or a memo'ed component; it would be shown as Anonymous
Refer this - https://github.com/facebook/react/issues/17876
Or try solutions mentioned here - React Dev tools show my Component as Unknown

Resources