SushiRiceOverEggs
SushiRiceOverEggs

Reputation: 312

useNavigate state is null?

Im trying to figure out why is it that when I use useNavigate with my first component the state appears null when I render my second component?

I've checked the answers found here but did not find any luck :Cannot pass state using useNavigate() in react router dom v6

Here's my code from first component:

export default SignInPage(){

const loginEmailRef = useRef('');
const loginPassWordRef = useRef('');
const navigate = useNavigate();

    return(
      <Box className='sign-in-textfield-box' display='flex' flexDirection='column' alignItems='center'>
                <TextField variant='standard' label='email' sx={{ mb: 2, width: '30vw' }} inputRef={loginEmailRef} />
                <TextField variant='standard' label='password' type='password' sx={{ width: '30vw' }} inputRef={loginPassWordRef} />
                <Button
                    sx={{ mt: 5, fontSize: '17px', }}
                    onClick={async (event) => {
                        event.preventDefault();
                        try {
                            const response = await signInUser(loginEmailRef.current.value, loginPassWordRef.current.value);
                            if (response !== 'error') {
                                console.log('response: ', response);

                                ********************************
                                // response does exist as an object with {name: ..., email:... etc}, but when i pass the response with navigate it says null on my other page
                                  navigate('/HomePage', {state: {response}});
                     
                                ********************************
        
                                //   <Link to={'/HomePage'} state={{state: response} }/>
                            } else {
                                alert('Error signing in: ', response);
                            }
                            // history('/HomePage');
                        } catch (error) {
                            console.log('error puhsing to page: ', error);
                        }
                    }}>SignIn</Button>
            </Box>
    );
}

Here's the code on my other page:

export default HomePage(props) {


const {state} = useLocation();

useEffect( ()=> {

    // here consolo.log says state: null
    console.log(    
        'state: ', state
    );
}, [])
    return(
     <Box> Something here </Box>
);
}

EDIT:

Response from response

Object { 
  providerId: "firebase", 
  proactiveRefresh: {…}, 
  reloadUserInfo: {…}, 
  reloadListener: null, 
  uid: "some-user-id-here", 
  auth: {…}, 
  stsTokenManager: {…}, 
  accessToken: 'some-token-here', 
  displayName: null, 
  email: "[email protected]", … 
}

​The initial page is SignInPage() then once the user successfully signed it he/she will be redirected to HomePage()

My App.js:

import { Route, Routes } from 'react-router-dom';
import HomePage from './components/Pages/HomePage/HomePage';
import SignInAndUpPage from './components/Pages/SignInAndUp/SignInAndUpPage';

function App() {
   return (
      <div>
        <Routes>
          <Route path='/' element={<SignInAndUpPage />} />
          <Route path='/HomePage' element={<HomePage />} />
        </Routes>
     </div>
  );
}

export default App;

EDIT # 2: signInUser method:

export async function signInUser(email, password) {
    try {
       
       const response = await signInWithEmailAndPassword(auth, email, password);
       console.log('sign in successful. UID: ', response.user.uid);
       const uid = await loadUserData(response.user.uid)
    
       return response.user;
    } catch (error) {
       console.log('error signin use: ', error.message);
       return 'error';
    }
}

Upvotes: 2

Views: 5653

Answers (1)

Drew Reese
Drew Reese

Reputation: 202618

Values sent in route state should be serializable. Perhaps one of these {...} response object values contains a non-serializable object, like a function.

Response from response

Object { 
  providerId: "firebase", 
  proactiveRefresh: {…}, // <-- serializable?
  reloadUserInfo: {…}, // <-- serializable?
  reloadListener: null, 
  uid: "some-user-id-here", 
  auth: {…}, 
  stsTokenManager: {…},  // <-- serializable?
  accessToken: 'some-token-here', 
  displayName: null, 
  email: "[email protected]",
  … 
}

For example, functions are typically named using a verb, as in, the function is doing some action. The reloadUserInfo sounds like it invokes an action.

Instead of blindly passing the entire response object in route state, select only the properties necessary for the receiving route.

Example:

const response = await signInUser(
  loginEmailRef.current.value,
  loginPassWordRef.current.value
);

if (response !== 'error') {
  console.log({ response });

  // response does exist as an object with {name: ..., email:... etc}
  const { accessToken, email, name, uid } = response;
  const state = { accessToken, email, name, uid };
  navigate('/HomePage', { state });
} ...

Upvotes: 3

Related Questions