开发者问题收集

useNavigate 状态为空?

2022-04-09
5366

我试图弄清楚为什么当我在第一个组件中使用 useNavigate 时,在渲染第二个组件时 state 会出现 null

我检查了在这里找到的答案,但没有找到任何运气: 无法在 react router dom v6 中使用 useNavigate() 传递状态

这是我的第一个组件的代码:

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>
    );
}

这是我的其他页面上的代码:

export default HomePage(props) {


const {state} = useLocation();

useEffect( ()=> {

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

编辑:

来自的回复 response

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

初始页面是 SignInPage() ,一旦用户成功签名,他/她将被重定向到 HomePage()

我的 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;

编辑#2: signInUser 方法:

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';
    }
}
1个回答

在路由状态中发送的值应该是可序列化的。这些 {... 响应对象值之一可能包含不可序列化的对象,如函数。

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]",
  … 
}

例如,函数通常使用动词命名,例如,函数正在执行 某些 操作。 reloadUserInfo 听起来像是在调用某个操作。

不要盲目地在路由状态中传递整个响应对象,而应仅选择接收路由所需的属性。

示例:

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 });
} ...
Drew Reese
2022-04-11