Hello i am getting error while using useContext in react.
error Cannot read properties of undefined (reading 'state');
problem is in about.js
my app.js
import './App.css';
import {BrowserRouter as Router,Routes ,Route,} from "react-router-dom";
import Navbar from './components/Navbar';
import { Home } from './components/Home';
import { About } from './components/About';
import NoteState from './context/notes/NoteState';
function App() {
return (
<div className="main">
<NoteState>
<About />
</NoteState>
<Router>
<Navbar />
{/* <LoadingBar
color='#f11946'
height={3}
progress={progress}
/> */}
<Routes>
<Route exact path="/" element={<Home />}></Route>
<Route exact path="/about" element={<About />}></Route>
</Routes>
</Router>
</div>
);
}
export default App;
error is in About.js
import React, {useContext, useEffect} from 'react'
//import NoteState from '../context/notes/NoteState';
import NoteContext from '../context/notes/noteContext';
export const About = () => {
const a = useContext(NoteContext)
useEffect(() => {
a.update();
// eslint-disable-next-line
}, [])
return (
<div>my name is {a.state.name}</div>
)
}
my note context.js where i created createContext
import { createContext } from "react";
const NoteContext = createContext();
export default NoteContext;
and finally my noteState.js where i useContext and pass the props
import NoteContext from "./noteContext";
import { useState } from "react";
const NoteState = (props)=> {
const s1 = {
"name": "Harry",
"class": "5b"
}
const [state, setState] = useState(s1);
const update = ()=>{
setTimeout(() => {
setState({
"name": "Larry",
"class": "10b"
})
}, 1000);
}
return (
<NoteContext.Provider value={{state:state, update:update}}>
{props.children}
</NoteContext.Provider>
)
}
export default NoteState;
i am learning react.js from old course and i am thinking that might be the case that some functions are change in new React.js which is the issue
Related
i am trying to use the useContext hook for the first time and i am not getting the name displayed on screen, i have never used useContext ever before, so pls a little bit of explination of my mistake will be appreciated. Here is the code:
(edit: added App.js)
AuthContext.js
const AuthContext = createContext()
export default AuthContext;
export const AuthProvider = ({children}) => {
return (
<AuthContext.Provider value={{'name':"Dennis"}}>
{children}
</AuthContext.Provider>
)
}
Header.js
import React, { createContext, useContext } from 'react'
import { Link } from 'react-router-dom'
import AuthContext from '../context/AuthContext'
const Header = () => {
let { name } = useContext(AuthContext)
return (
<div>
<Link to="/">Home</Link>
<span> </span>
<Link to="/login">Login</Link>
<h1>Hello {name}</h1>
</div>
)
}
export default Header
App.js
import './App.css';
import {
BrowserRouter,
Routes,
Route,
} from "react-router-dom";
import HomePage from './pages/HomePage';
import LoginPage from './pages/LoginPage';
import Header from './components/Header';
import PrivateRoute from './utils/PrivateRoute'
import AuthProvider from './context/AuthContext';
function App() {
return (
<div className="App">
<BrowserRouter>
<AuthProvider>
<Header />
<Routes>
<Route path="/" element={ <PrivateRoute> <HomePage /> </PrivateRoute>} />
<Route path="/login" element={<LoginPage />} />
</Routes>
</AuthProvider>
</BrowserRouter>
</div>
);
}
export default App;
i have added the error screenshot
import AuthProvider from './context/AuthContext';
Instead of the above, you have to import the AuthProvider like below since you have used named export for AuthProvider in the AuthContext.js file.
import { AuthProvider } from './context/AuthContext';
If I am using react-query and react-router, I can see the network requests happening when navigating, however the new data is not reflected in the view/page? Am I doing something wrong? I am doing lazy loading:
App.tsx
import React, { Suspense } from 'react';
import Loader from '../loader/Loader';
const App: React.FunctionComponent = () => {
const Routing = React.lazy(() => import('../routing/Routing'));
return (
<>
<Suspense fallback={<Loader />}>
<DataProvider>
<Routing />
</DataProvider>
</Suspense>
</>
);
}
export default App;
router component:
import React from 'react';
import { BrowserRouter, Route, Switch} from 'react-router-dom';
import Header from '../header/Header';
import Component1 from './Component1';
import Compontent2 from './Component2';
import { QueryClient, QueryClientProvider } from 'react-query';
import { RouteComponentProps } from "react-router-dom";
const queryClient = new QueryClient()
const Routing: React.FunctionComponent = () => {
return (
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<Header />
<div className="App">
<Switch>
<Route exact path="/" component={Component1} />
<Route path="/details/:id" render={(props: RouteComponentProps<any>) => <Component2 {...props}/>} />
</Switch>
</div>
</BrowserRouter>
</QueryClientProvider>
)
}
export default Routing;
Component 1
const fetchAll = async () => {
const res = await fetch('https:xxxxxx/xxxxx');
return res.json();
};
const { data: result, status } = useQuery('info', fetchAll, {
staleTime: 0,
});
component 2 is using the same approach the react-query stuff is not in useEffect of anything?
How can I get the view to re-render on navigation and show the new data.
try and move the call to React.lazy outside of the fallback component?
const Routing = React.lazy(() => import('../routing/Routing'));
const App: React.FunctionComponent = () => {
return (
<>
<Suspense fallback={<Loader />}>
<DataProvider>
<Routing />
</DataProvider>
</Suspense>
</>
);
}
export default App;
That's how they're using it in the official React docs here:
https://reactjs.org/docs/code-splitting.html
EDIT: I imported something wrong :facepalm:
Let me first run down what code ive written to get this output then I will tell you the expected output and what im confused about
App.jsx
import React from "react";
import Home from "./components/pages/HomePage";
import store from "./ducks/store";
import { Provider } from "react-redux";
import { BrowserRouter, Route, Switch } from "react-router-dom";
const App = () => {
return (
<BrowserRouter>
<Provider store={store}>
<Switch>
<Route exact path="/" component={Home} />
</Switch>
</Provider>
</BrowserRouter>
);
};
export default App;
Home.jsx
import React, { useEffect } from "react";
import FlexBox from "../../shared/FlexBox";
import BlogPostList from "./SortSettings";
import { useSelector, useDispatch } from "react-redux";
import { fetchAllBlogs } from "../../../ducks/blogs";
import {
getBlogData,
getBlogPosts,
getBlogTags,
} from "../../../ducks/selectors";
import SpinLoader from "../../shared/SpinLoader";
const Home = () => {
const blogData = useSelector((state) => getBlogData(state));
const blogPosts = useSelector((state) => getBlogPosts(state));
const blogTags = useSelector((state) => getBlogTags(state));
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchAllBlogs());
}, [dispatch]);
// TODO: handle if blogData.requestError comes back as true
if (blogData.isLoading || !blogPosts || !blogTags) {
return (
<FlexBox
alignItems="center"
justifyItems="center"
width="100vw"
height="100vh"
>
<SpinLoader />
</FlexBox>
);
}
return (
<FlexBox height="100vh" width="100vw">
<BlogPostList blogPosts={blogPosts} />
</FlexBox>
);
};
export default Home;
BlogPostList.jsx
import React from "react";
import BlogPost from "./BlogPost";
import FlexBox from "../../shared/FlexBox";
const BlogPostList = ({ blogPosts }) => {
return (
<FlexBox flexDirection="column">
Why in the world is this rendering a SortSettings component AHHHHHH!
</FlexBox>
);
};
export default BlogPostList;
Now my question is this why is it that the Home component is rendering a component as showed here https://gyazo.com/8cac1b28bdf72de9010b0b16185943bb what I would expect the Home component to be rendering is a BlogPostList if anyone has an idea help would be appreciated ive been stuck on this for awhile now (im pretty new so this might just be a noob mistake so sorry if its something obvious)
I want to use history explicitly. So I know about BrowserRoute but I want to use Route and use history as its property. when I run the program I get this page.enter image description here
This is my AppRouter.js
import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import LoginPage from "../components/LoginPage";
import ExpenseDashboardPage from "../components/ExpenseDashboardPage";
import AddExpensePage from "../components/AddExpensePage";
import EditExpensePage from "../components/EditExpensePage";
import NotFoundPage from "../components/NotFoundPage";
import PublicRoute from "./PublicRoute";
import PrivateRoute from "./PrivateRoute";
export const history = createBrowserHistory();
const AppRouter = () => (
<Router history={history}>
<div>
<Switch>
<PublicRoute path="/" component={LoginPage} exact={true} />
<PrivateRoute path="/dashboard" component={ExpenseDashboardPage} />
<PrivateRoute path="/create" component={AddExpensePage} />
<PrivateRoute path="/edit/:id" component={EditExpensePage} />
<Route component={NotFoundPage} />
</Switch>
</div>
</Router>
);
export default AppRouter;
LoginPage.js
import React from "react";
import { connect } from "react-redux";
import { startLogin } from "../actions/auth";
export const LoginPage = ({ startLogin }) => (
<div>
<button onClick={startLogin}>Login with Google</button>
<button>Amir Hossein Jobeiri</button>
</div>
);
const mapDispatchToProps = (dispatch) => ({
startLogin: () => dispatch(startLogin()),
});
export default connect(undefined, mapDispatchToProps)(LoginPage);
PublicRoute.js
import React from "react";
import { connect } from "react-redux";
import { Route, Redirect } from "react-router-dom";
export const PublicRoute = ({
isAuthenticated,
component: Component,
...rest
}) => (
<Route
{...rest}
component={(props) =>
isAuthenticated ? <Redirect to="/dashboard" /> : <Component {...props} />
}
/>
);
const mapStateToProps = (state) => ({
isAuthenticated: !!state.auth.uid,
});
export default connect(mapStateToProps)(PublicRoute);
PrivateRoute
import React from "react";
import { connect } from "react-redux";
import { Route, Redirect } from "react-router-dom";
import Header from "../components/Header";
export const PrivateRoute = ({
isAuthenticated,
component: Component,
...rest
}) => (
<Route
{...rest}
component={(props) =>
isAuthenticated ? (
<div>
<Header />
<Component {...props} />
</div>
) : (
<Redirect to="/" />
)
}
/>
);
const mapStateToProps = (state) => ({
isAuthenticated: !!state.auth.uid,
});
export default connect(mapStateToProps)(PrivateRoute);
I searched a lot about this problem but I do not get the right answer. Please help if you can.
I changed my "history" version to "4.7.2". It works properly.
I have recently experienced some issues with my react router and redux. Basically, I have a redux value set which let's me know if an item is selected. If the item is selected, then it will allow a URL to be used. One thing that I have noticed. If I add a redirect function. It breaks everything
Authentication function:
import React, { Component, Fragment } from "react";
import { Provider } from "react-redux";
// import store from "./store";
import {
BrowserRouter as Router,
Switch,
Route,
Redirect
} from "react-router-dom";
import { connect } from "react-redux";
import Profile from "./Profile";
import AddDomain from "./AddDomain";
import ChoosePackage from "./ChoosePackage";
import DashboardHome from "./DashboardHome";
import { Elements } from "#stripe/react-stripe-js";
import PropTypes from "prop-types";
import { loadStripe } from "#stripe/stripe-js";
const stripePromise = loadStripe("pk_test_7S0QSNizCdsJdm9yYEoRKSul00z4Pl6qK6");
class index extends Component {
componentDidMount() {
console.log("DOMAIN NAME" + this.props.domain_name);
}
state = {
domain_name: ""
};
static propTypes = {
domain_name: PropTypes.string.isRequired
};
domainCheck = () => {
if (this.props.domain_name != "") {
return <ChoosePackage />;
} else {
console.log("running rediect");
return <Redirect to="/dashboard" />;
}
};
render() {
return (
<React.Fragment>
<Route path="/dashboard/add-domain/choose-package">
{this.domainCheck()}
</Route>
<Route exact path="/dashboard/add-domain">
<AddDomain />
</Route>
<Route exact path="/dashboard/profile">
<Profile />
</Route>
<Route exact path="/dashboard">
<DashboardHome />
</Route>
</React.Fragment>
);
}
}
const mapStateToProps = state => ({
domain_name: state.domain.domain_name
});
index.defaultProps = {
domain_name: ""
};
export default connect(mapStateToProps, { pure: false })(index);
Any help is greatly appreciated