i am trying to implement the history.push prototype inside useEffect hook . this is how I did it :
useEffect(()=>
{
reset()
props.history.push('/')
},[signUpSuccess])
I have tried to import useHistory , yet its no longer supported
As you said, useHistory is no longer supported. It has been replace by useNavigate in react-router version 6. You can use it like this:
const history= useNavigate()
history('/')
instead of:
const history = useHistory()
history.push('/')
EDIT CONCERNING THE AUTOMATIC REDIRECT ON CLICK
The React documentation states:
If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.
This means that the code inside the useEffect hook will be executed each time the component will be rendered/updated.
Related
In the code snip below, execution never reaches to useNavigate() line. It terminates at useContext() line without any error message. However, I managed to use useContext at another place without any issue. That makes me to think problem is related with, where and how I call logOut and relatedly useContext.
import AuthContext from '../store/auth-context';
import { useState, useRef, useContext } from 'react';
export default function LogOut() {
const authCtx = useContext(AuthContext);
const navigator = useNavigate();
authCtx.logout();
// optional: redirect the user
navigator('/dbsection');
return;
};
The place where LogOut is called:
import logOut from '../components/logOut.js';
<NavBtn>
<NavBtnLink to='/formLogIn'>Log In</NavBtnLink>
<NavBtnLink to='/dbsection' onClick={logOut}>Log Out</NavBtnLink>
</NavBtn>
</Nav>
I tried to create an instance from useContext() hook. I wanted to call a function of related context but I couldn't create the instance.
The reason of the problem is that useContext hook is called/triggered via onClick handle. I dont know why but for some reason, React doesnt allow this. I just moved content of external 'logOut' function into the component where I call logOut, and useContext worked as well.
Why React doesnt allow useContext hook, or maybe all hooks to be called through onClick handle, thats still a question for me.
Context
I'm working with a hybrid next.js and react-router app. Parts of the app are handled by react-router (hash-based), and parts of it by next.js router. There are common components which use hooks related to the current routing state (e.g. useLocation), which crash if the react-router provider wrapper is missing.
Problem
I would like to write a hook that returns either useLocation (from react-router-dom) or useRouter (from next.js), depending on whether it detect the react-router provider in the current context.
Then I would use this hook in common components, so that they work regardless of which context they're used in.
There is a similar solution for detecting whether to use useEffect or useLayoutEffect for SSR, called useIsomorphicLayoutEffect. I'm thinking that a similar approach could work in my case. However, feel free to suggest different solutions.
The error I'm getting is TypeError: useContext(...) is undefined. The react-router wrapper provides a context which is used by the useLocation hook. Therefore I believe a generic solution for detecting the context provider would be valid here.
Example
const fooCommonComponent = () => {
// ❌ this only works when react-router-dom provider exists in the current context
const { pathname } = useLocation();
// ❌ this only works for next.js router
const { pathname } = useRouter();
// ✅ what i want
const { pathname } = useCustomLocation();
};
const useCustomLocation = () => {
// how to implement this?
};
I'm not very familiar with the Next.js side of things, but react-router-dom#6 has an useInRouterContext hook to return true/false if the component is rendered within a RRD routing context.
useInRouterContext
The useInRouterContext hooks returns true if the component is
being rendered in the context of a <Router>, false otherwise. This
can be useful for some 3rd-party extensions that need to know if they
are being rendered in the context of a React Router app.
Here's an example implementation that works for at least the RRD side of things.
import { useInRouterContext, useLocation } from "react-router-dom";
import { useRouter } from "next/router";
const useCustomLocation = () => {
const isInRRDContext = useInRouterContext();
return (isInRRDContext ? useLocation : useRouter)() ?? {};
};
getting in valid hook error in a re write of a clients app... (upgrading code)
mobx 6.3.8 mobx react 7.2.1 and mobx-state-tree 5.0.5
React 17.0.1 RN 0.64.3
i feel like the error is here. i googled the code line for use stores and it led me to the deprecated site... i dont know where to find new handling in the https://mobx.js.org/react-integration.html site... what would this be called?
import { createContext, useContext } from "react"
import { RootStore } from "./root-store"
const RootStoreContext = createContext<RootStore>({} as RootStore)
const RootStoreProvider = RootStoreContext.Provider
// hook error here? // export const useStores = () => useContext(RootStoreContext);
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:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
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.
adding more context... rootstore file
import { Instance, SnapshotOut, types } from "mobx-state-tree"
import { creatMediaPlayerModel } from "../../models/media-player"
import { createUserModel } from "../../models/user"
import { createContentModel } from "../../models/content"
export const RootStoreModel = types.model("RootStore", {
mediaPlayerStore: creatMediaPlayerModel(),
userStore: createUserModel(),
contentStore: createContentModel(),
})
export type RootStore = Instance<typeof RootStoreModel>
export type RootStoreSnapshot = SnapshotOut<typeof RootStoreModel>
From that error message:
Hooks can only be called inside of the body of a function component.
You are not calling a hook from inside the body of a function component. So you are breaking the rules of hooks.
According the rules of hooks you can only call a hook from the top level of a react function component. If you are not inside a functional component, then you cannot use a react hook*.
From the docs:
Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function, before any early returns. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls.
That means you need to call useStores from within a functional component.
Something like:
function MyComponent() {
const myStores = useStores()
// render component with data from stores here
return <>{myStore.myData}</>
}
* The exception, sort of, is a custom hook which can call other hooks. Your useStores here is a custom hook. So it's fine to call useContext from that custom hook.
But that custom hook must obey the same usage rules as the built in hooks, so all hooks are called from the body of a function component, there is just function in between.
Have a ReactJS + Redux + Saga application that was recently updated to use the latest (or close to latest) versions of the respective JS libraries. After the library updates (no code changes) and running the application, I immediately see the "Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state." warning message in the console. It looks to be triggered by redux when I invoke the dispatch function (which then calls a function in Provider.js, then goes through react-dom, and then in turn writes the warning message. Again nothing in my code has changed, and my code is essentially built using stateless functions.
Not sure how to go about figuring out what is causing this warning-- although the app still runs ok as expected. Using React 16.8.6, react-redux 6.0.1, react-router-dom 5.0.0, redux 4.0.1, redux-saga 1.0.2, and connected-react-router 6.4.0.
Below is a sample page that would cause the warning message:
import React from 'react'
import {connect} from 'react-redux'
import {links} from '../links'
import {notify} from '../notifications'
const Home = props => {
const {dispatch} = props
return (
<main>
<p>
Go to Details...
</p>
</main>
)}
const dispatcher = dispatch => {
dispatch(notify(links.HOME))
return {dispatch}
}
export default connect(null, dispatcher)(Home)
You cannot call to dispatch inside the disaptcher function.
react-redux's connect parameters are:
function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)
mapDispatchToProps is what you called dispatch. These params are eventually run as functions that called in the render loop of the connected component. When you dispatch in the render loop it changes the state of a React component (looks like it's the Provider), which is forbidden by React.
Solution
Move the dispatch(notify(links.HOME)) to lifecycle method. For example you can add to the Home component (this will require to rewrite the Home component as an extension of React.Component class:
componentDidMount() {
dispatch(notify(links.HOME))
}
UPDATE
If you want to do this with classless component see that question
I have a functional Component which is using the hook useCallback. For the last few days everything was just fine. All worked as it should. Today I start up the app and I have this error:
React Hook "useCallback" is called in function "loginPage" which is neither a React function component or a custom React Hook function
This makes no sense because it has been fine. For debugging I simply erased all code on the page except that one coed and even just put a useCallback template in its place, but still the same. It is as if it has been removed from react entirely.
I checked my react version and find 16.8.6 also in react-dom.
Does anyone have any ideas?
import React, {Fragment,useCallback } from 'react';
import { Redirect} from 'react-router-dom';
import {useDropzone} from 'react-dropzone';
const loginPage = (props) => {
const callbackFunction = useCallback(() => {
console.log("callback called");
// Do something with callbackCount ...
return true;
}, []);
}
I see three problems why the error occurred.
which is neither a React function component or a custom React Hook function
loginPage is not a component. useCallback is a hook and it needs to be called inside a function component (not a class component) or in another hook (a function whose name starts with "use"). Check out the rules of hooks.
And also the component name should start with a capital letter, so it should be LoginPage for it to be a valid React component.
You are not returning anything from your component.