What I'm trying to do is to call my service on the main page and then assign context to the response and print it in another component. I can print but when I refresh the page I get an error.
home.js
import React, { useContext, useEffect } from 'react';
import { PolicyContext } from 'contexts/PolicyContext';
import { PolicyService } from 'services/PolicyService';
const Home = () => {
const { policyData, setPolicyData } = useContext(PolicyContext);
const activiesPolicyExampleReq = {
nationalId: '59104492600',
};
useEffect(() => {
PolicyService.getActivePolicies(activiesPolicyExampleReq).subscribe(
(response) => {
setPolicyData(response);
}
);
}, []);
}
PolicyContext.js
import React, { createContext, useMemo, useState } from 'react';
export const PolicyContext = createContext(undefined);
const PolicyContextProvider = (props) => {
const [policyData, setPolicyData] = useState();
console.log('PC');
return (
<PolicyContext.Provider
value={useMemo(() => {
return ({
policyData,
setPolicyData,
});
}, [{ policyData, setPolicyData }])}
>
{props.children}
</PolicyContext.Provider >
);
};
export default PolicyContextProvider;
App.js
import { Route, Router } from 'react-router-dom';
import AppRouter from 'routes/AppRouter';
import { CookiesProvider } from 'react-cookie';
import Header from 'modules/Header';
import Login from 'pages/login/login';
import Onboarding from './pages/onboarding/onboarding';
import PolicyContextProvider from './contexts/PolicyContext';
import React from 'react';
import Theme from 'theme/Theme';
import { history } from './libs/History';
export default function App() {
return (
<Theme>
<CookiesProvider>
<PolicyContextProvider>
<Router history={history}>
<Route exact path={['/onboarding']} component={Onboarding} />
<Route exact path={['/login']} component={Login} />
<Header />
<AppRouter />
</Router>
</PolicyContextProvider>
</CookiesProvider>
</Theme>
);
}
the component i want to print
const { policyData, setPolicyData } = useContext(PolicyContext);
console.log(policyData);
<TabPanel value={value} index={0}>
<PolicyCarousel
policyList={
policyData.activePoliciesMap
? policyData.activePoliciesMap[policiesMapType]
: null
}
policyType={0}
/>
</TabPanel>
error in console:
Cannot read properties of undefined (reading 'activePoliciesMap')
Related
I am trying to use React and useRoutes, but I get an error and nothing is displayed. I can't figure out where the problem is, can you help me? Thank you very much
This is the error
routes.js:12 Uncaught TypeError: Cannot read properties of undefined (reading 'createElement')
at routes.js:12:17
..
These are my files
App.jsx contains the import of BrowserRouter
import Index from './Index.jsx';
import { BrowserRouter as Router, Link } from "react-router-dom";
import { Menu } from './Menu.jsx';
export const App = () => (
<div>
<Router>
<Menu />
<Index />
</Router>
</div>
);
Index.jsx containing the useRoutes
import { useRoutes } from "react-router-dom";
import { routes } from "./routes";
export const Component = () => {
let element = useRoutes(routes);
return element;
};
export default Component;
router.js where all routes will be declared
import { React } from "react";
import { Home } from './Home.jsx';
import { ErrorPage } from './ErrorPage.jsx';
export const routes = [
{
path:'/',
element:<Home />
},
{
path:'*',
element:<ErrorPage />
}
];
Menu.jsx containing the site menu and consequently the Links
import React, { useState } from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import { pages } from '../../data/pages';
export const MenuTop = () => {
const [myPages, setMyPages] = useState(pages);
const [pageToDisplay, setPageToDisplay] = useState("/");
const displayPage = (page) => {
setPageToDisplay(page.url);
}
return (
<Router>
<div className="ui menu">
{myPages.map((el) => {
const { id, name, url } = el;
return (
<Link to={url} key={id} className={`item ${pageToDisplay == url ? "active" : ""}`} onClick={() => displayPage({url})}>{name}</Link>
);
})}
</div>
</Router>
);
}
The issue is that you're importing the wrong React, using a named export instead of a default one. Here is the error, in the router.js/routes.js:
On the first line, import { React } from 'react'
import { React } from "react";
import { Home } from './Home.jsx';
import { ErrorPage } from './ErrorPage.jsx';
export const routes = [
{
path:'/',
element:<Home />
},
{
path:'*',
element:<ErrorPage />
}
];
Change it to a default export:
import React from "react";
import { Home } from './Home.jsx';
import { ErrorPage } from './ErrorPage.jsx';
export const routes = [
{
path:'/',
element:<Home />
},
{
path:'*',
element:<ErrorPage />
}
];
This should fix the issue.
It's the HomePage component of ReactJS
import React from 'react';
import axios from 'axios';
import { useState, useEffect } from 'react';
import { useNavigate,useParams } from 'react-router-dom';
import { Main } from '../components/Main';
import { Controls } from '../components/Controls';
import { ALL_COUNTRIES } from '../config';
import { List } from '../components/List';
import { Card } from '../components/Card';
import { Details } from './Details';
export const HomePage = () => {
const [countries,setCountries] = useState([]);
const navigate = useNavigate();
useEffect(() => {
axios.get(ALL_COUNTRIES).then(({data})=>setCountries(data))
},[]);
return (
<>
<Controls/>
<List>
{
countries.map((c) => {
const countryInfo = {
img: c.flags.png,
name: c.name,
info: [
{
title:'Population',
description:c.population.toLocaleString(),
},
{
title:'Region',
description:c.region,
},
{
title:'Flag',
description:c.capital,
},
],
};
return (
<Card
key={c.name}
onClick={(e) => {
navigate('/country/${c.name}');
}}
{...countryInfo}
/>
)
})
}
</List>
</>
);
};
It's second components Details
import React from 'react';
import { useParams } from 'react-router-dom';
export const Details = ({match,params}) => {
const { name } = useParams();
return (
<div>
Details {match.params.name}
</div>
);
};
config.js
const BASE_URL = 'https://restcountries.com/v2/';
export const ALL_COUNTRIES=BASE_URL+"all?fields=name,flags,population,capital,region";
export const searchByContry=(name)=>BASE_URL+'name/'+name;
export const filterByCode=(code)=>BASE_URL+'alpha?code'+code.join('');
APP.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
import { Route,Routes,Router,useParams} from 'react-router-dom';
import {useState, useEffect} from 'react';
import './App.css';
import styled from 'styled-components';
import Header from './components/Header';
import { Main } from './components/Main';
import {NotFound} from './pages/NotFound';
import { HomePage } from './pages/HomePage';
import { Details } from './pages/Details';
function App() {
return (
<>
<Header/>
<Main>
<Routes>
<Route path="/" element={<HomePage/>}/>
<Route path="country/:name" element={<Details/>}/>
<Route path="*" element={<NotFound/>}/>
</Routes>
</Main>
</>
);
}
export default App;
HomePage itself looks like this
but when I click on flag/card it sends me on second page as expected but gives me this error
[2]:https://i.stack.imgur.com/39HEw.png
Also, I'm using react-router-domV6 and Axios
and this API https://restcountries.com/v2/all
also both Components are in
APP.js
Details is trying to read params from an undefined object, props.match in this case.
<Route path="country/:name" element={<Details />} /> // <-- no props passed!
...
import React from 'react';
import { useParams } from 'react-router-dom';
export const Details = ({ match, params }) => { // <-- match undefined
const { name } = useParams();
return (
<div>
Details {match.params.name} // <-- Oops, can't read params of undefined
</div>
);
};
Remove the props and access the values returned from the useParams hook.
import React from 'react';
import { useParams } from 'react-router-dom';
export const Details = () => {
const { name } = useParams();
return (
<div>
Details {name}
</div>
);
};
The target path is also malformed. The code navigate('/country/${c.name}') is navigating to the string literal "/country/${c.name}", which is likely not what you meant to do. Fix this to use a string template literal instead to inject the c.name value into the target path.
navigate(`/country/${c.name}`) // note the backticks instead of single quotes
I oftentimes find it useful/helpful to use the generatePath utility function to create path values.
Example:
import { generatePath, useNavigate } from 'react-router-dom';
...
const path = generatePath("/country/:name", { name: c.name });
navigate(path);
I am trying to access LaunchDarkly flags from my App context. The code looks like:
import { useState, useEffect } from 'react';
import { Helmet } from 'react-helmet';
import { MuiPickersUtilsProvider } from '#material-ui/pickers';
import DateFnsUtils from '#date-io/date-fns';
import { ApolloProvider } from 'react-apollo';
import { Route, Router, Switch } from 'react-router-dom';
import { withLDProvider } from 'launchdarkly-react-client-sdk';
import { Loading } from '#ap/owl-ui-controls';
import { useAuth0 } from './context/Authentication';
import LabelContext from './context/LabelContext';
import { CommunityByNameContext } from './context/CommunityByNameContext';
import { segment_init } from './utils/segment';
import withConfig, { ConfigEnum } from './utils/withConfig';
import client from './utils/graphQLClient';
import labels from './config/labels';
import CurrentUser from './services/CurrentUser';
import Layout from './Layout';
import history from './utils/history';
import { SearchCommunity } from './common/Filters/SearchNameFilter/findCommunitiesQuery';
import AmplitudeContext, { AmplitudeData } from './context/AmplitudeContext';
import { DisclosuresContextProvider } from './context/DisclosuresContext';
import placeService from './services/placesService';
import { FeaturedCommunitiesIdsProvider } from './context/FeaturedCommunitiesIdsContext';
import { optimizelyInit } from './utils/optimizely';
import { FamilyFileContextProvider } from './context/FamilyFileContext';
const segmentKey = withConfig(ConfigEnum.SEGMENT_KEY);
const currentUserString = localStorage.getItem('CURRENT_USER');
const App = () => {
const { loading } = useAuth0();
const [currentUser, setCurrentUser] = useState(currentUserString ? JSON.parse(currentUserString) : null);
const [communityByName, setCommunityByName] = useState<SearchCommunity | null>(null);
const [amplitude, setAmplitude] = useState<AmplitudeData>({});
useEffect(() => {
placeService.init();
}, []);
if (loading) {
return <Loading />;
}
return (
<>
<Helmet>
<title>Beacon</title>
<script type="text/javascript">{optimizelyInit(flags)}</script>
<script type="text/javascript">{segment_init(segmentKey, currentUser)}</script>
</Helmet>
<LabelContext.Provider value={labels}>
<CommunityByNameContext.Provider value={{ communityByName, setCommunityByName }}>
<FeaturedCommunitiesIdsProvider>
<AmplitudeContext.Provider value={{ amplitude, setAmplitude }}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<ApolloProvider client={client}>
{/* #ts-ignore */}
<CurrentUser onUserChanged={(currentUser: any) => setCurrentUser(currentUser)}>
<FamilyFileContextProvider>
<DisclosuresContextProvider>
<Router history={history}>
<Switch>
<Route path="/communities" component={Layout} />
</Switch>
</Router>
</DisclosuresContextProvider>
</FamilyFileContextProvider>
</CurrentUser>
</ApolloProvider>
</MuiPickersUtilsProvider>
</AmplitudeContext.Provider>
</FeaturedCommunitiesIdsProvider>
</CommunityByNameContext.Provider>
</LabelContext.Provider>
</>
);
};
export default withLDProvider({
clientSideID: withConfig(ConfigEnum.LD_CLIENT_SIDE_ID),
})(App);
My nested components, like for example <CurrentUser /> get LD flags, and I am able to access them as:
const CurrentUser = ({ children, flags, onUserChanged })
However, I also need LD flags inside <App /> so I could do:
<Helmet>
<title>Beacon</title>
{flags.optimizely && <script type="text/javascript">{optimizelyInit(flags)}</script>}
<script type="text/javascript">{segment_init(segmentKey, currentUser)}</script>
</Helmet>
I have tried accessing flags with const App = ({ flags }), but the value is always undefined.
I even tried sticking the below into a component
const DocumentHead = ({ flags, segmentKey, currentUser }) => (
<Helmet>
<title>Beacon</title>
<script type="text/javascript">{optimizelyInit(flags)}</script>
<script type="text/javascript">{segment_init(segmentKey, currentUser)}</script>
</Helmet>
);
Flags are still undefined.
Suggestions?
Apparently, there is a useFlags hook. We can get flags as:
const flags = useFlags();
This can be called from the <App /> component.
native-info package like tutorial but just enters once and initial render, I implemented App.js is my initial rendering page and I use redux and react nativagiton to App.js return method I confuse why console.warn triggered once and initial render, my App.js code like below
import {SafeAreaProvider} from 'react-native-safe-area-context';
import {Provider} from 'react-redux';
import {PersistGate} from 'redux-persist/integration/react';
import {NavigationContainer} from '#react-navigation/native';
import { SafeAreaProvider } from "react-native-safe-area-context";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { NavigationContainer } from "#react-navigation/native";
export default function App() {
let navigator;
const [netInfo, setNetInfo] = useState("");
const [netConnection, setNetConnection] = useState(false);
useEffect(() => {
const unsubscribe = NetInfo.addEventListener((state) => {
setNetInfo({
isConnected: state.isConnected,
});
});
return () => {
unsubscribe();
};
}, []);
useEffect(() => {
console.warn(netInfo.isConnected);
if (netInfo.isConnected === undefined) {
if (netInfo.isConnected) {
setNetConnection(true);
} else {
setNetConnection(false);
}
}
}, [netInfo]);
return (
<Provider store={store}>
{netConnection && <RnModal show={netConnection} />}
<PersistGate loading={null} persistor={persistor}>
<SafeAreaProvider>
<NavigationContainer
ref={(nav) => {
navigator = nav;
}}
>
<Navigator />
</NavigationContainer>
</SafeAreaProvider>
</PersistGate>
</Provider>
);
}
I am following a tutorial from https://auth0.com/blog/role-based-access-control-rbac-and-react-apps/ and it seems that author doesn't support it anymore.
The idea is simple: Once a user presses Login button (on Header.js) he is redirected to auth0 page. There he enters his data and is redirected back to localhost:3000/callback route. This is when handleAuthentication is triggered.
Unfortunately, I am facing an issue when setting the state when the setSession function is used.
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in Auth (created by App)
in App
Here are the components:
App.js
import React from 'react'
import { Switch, Route, BrowserRouter as Router } from 'react-router-dom'
import Auth from './Auth';
import CallbackPage from "../pages/callback";
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Auth>
<div style={{width: '1280px', margin: '0 auto'}}>
<Router>
<Switch>
<Route exact path='/' component={HomePage} />
<Route path='/callback' component={CallbackPage} />
</Switch>
</Router>
</div>
</Auth>
)
}
}
export default App;
Auth.js
import React, {Component} from 'react';
import auth0 from 'auth0-js';
import {AUTH_CONFIG} from '../auth0-variables';
import {AuthProvider} from '../authContext';
const auth = new auth0.WebAuth({
domain: AUTH_CONFIG.domain,
clientID: AUTH_CONFIG.clientId,
redirectUri: AUTH_CONFIG.callbackUrl,
audience: `https://${AUTH_CONFIG.domain}/userinfo`,
responseType: 'token id_token'
});
class Auth extends Component {
state = {
authenticated: false,
}
initiateLogin = () => {
auth.authorize();
};
handleAuthentication = () => {
auth.parseHash((error, authResult) => {
if (error) {
console.log(error);
console.log(`Error ${error.error} occured`);
return
}
this.setSession(authResult);
})
};
setSession(authResult) {
this.setState({
// This does not update the state!!
authenticated: true,
});
};
render() {
const authProviderValue = {
...this.state,
initiateLogin: this.initiateLogin,
handleAuthentication: this.handleAuthentication,
};
return (
<AuthProvider value={authProviderValue}>
{this.props.children}
</AuthProvider>
)
}
};
export default Auth;
Header.js (Can component can be found at https://github.com/itaditya/react-rbac-auth0-article-code/blob/master/src/components/Can.js)
import React, { useEffect, useReducer } from 'react';
import {
BrowserRouter as Router,
Link }
from 'react-router-dom';
import Login from '../Login';
import Logout from '../Logout';
import Can from '../Can';
import { AuthConsumer } from '../../authContext';
const Header = (props) => {
return (
<AuthConsumer>
{({ user }) => (
<Can role={user.role} perform='home-page:seeLogin'
yes={() => (
<Login />
)}
no={() => (
<Logout />
)}
/>
</AuthConsumer>
)
}
export default Header
And pages:
homePage:
import React from 'react';
const HomePage = () => {
return (
<div>
<Header />
</div>
)
};
export default HomePage;
Callback page
import React from 'react';
import { Redirect } from 'react-router-dom';
import { AuthConsumer } from '../authContext';
const Callback = props => (
<AuthConsumer>
{({ handleAuthentication }) => {
if (/access_token|id_token|error/.test(props.location.hash)) {
handleAuthentication();
}
return <Redirect to='/' />;
}}
</AuthConsumer>
);
export default Callback;
Any help would be appreciated.