React Native:“渲染的钩子比预期的要少。”不知道这意味着啥,应用程序崩溃?
Posted
技术标签:
【中文标题】React Native:“渲染的钩子比预期的要少。”不知道这意味着啥,应用程序崩溃?【英文标题】:React Native: "Rendered fewer hooks than expected." No clue what this means, app crashes?React Native:“渲染的钩子比预期的要少。”不知道这意味着什么,应用程序崩溃? 【发布时间】:2021-07-19 20:47:33 【问题描述】:我有一个 AuthScreen 应该处理所有的登录、注册、忘记密码等逻辑。代码如下:
import React, useState from 'react';
import RootStateOrAny, useDispatch, useSelector from "react-redux";
import authForgotPassword, authLogin, authRegister from '../store/actions/authActions';
import ForgotPassword from '../components/Auth/ForgotPassword';
import Login from '../components/Auth/Login';
import PageType from '../utils/PageType';
import Register from '../components/Auth/Register';
import StackNavigationProp from '@react-navigation/stack';
type ParamList =
AuthLoadingScreen: undefined;
HomeTabScreen: undefined;
AuthScreen: undefined
type AuthScreenNavigationProp = StackNavigationProp<ParamList, 'AuthScreen'>;
type Props =
navigation: AuthScreenNavigationProp;
export default function AuthScreen( navigation : Props)
const dispatch = useDispatch();
const user = useSelector((state: RootStateOrAny) => state.auth.user);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [password2, setPassword2] = useState('');
const [showPage, setShowPage] = useState(PageType.Login);
const changePage = (pageType: PageType) =>
setEmail('');
setPassword('');
setPassword2('');
setShowPage(pageType);
const login = () =>
dispatch(authLogin(email, password));
const register = () =>
if (password === password2)
dispatch(authRegister(email, password));
else
alert('Passwords must match!');
const forgotPassword = () =>
dispatch(authForgotPassword(email, changePage));
if (user)
navigation.navigate('HomeTabScreen');
return null;
else
switch(showPage)
case PageType.Login:
return Login(email, setEmail, password, setPassword, changePage, login);
case PageType.Register:
return Register(email, setEmail, password, setPassword, password2, setPassword2, changePage, register);
case PageType.ForgotPassword:
return ForgotPassword(email, setEmail, changePage, forgotPassword);
default: return Login(email, setEmail, password, setPassword, changePage, login);
我有组件“登录”、“注册”和“忘记密码”,每个组件都显示(返回)不同的布局、操作等。
所以我制作了一个钩子和一个开关盒,例如在“登录”组件中按下“在此处注册”时,它将使用 REGISTER 页面值调用“changePage”。它应该重新渲染“AuthScreen”,看到“showPage”值更改为“REGISTER”,然后再次进入我的 switch-case,并返回“REGISTER”值。无论如何,这就是我的想法。
尝试设置 showPage 挂钩“setShowPage(pageType);”时发生错误在“changePage”功能中。如果我对此发表评论,应用不会崩溃,但也不会更改页面。
这是什么意思,我该如何修复我的屏幕?
【问题讨论】:
我认为它与您从 switch 语句返回组件的方式有关。 与你的问题无关,你考虑过使用 react-router 吗? @im_baby 不,您也可以将它与 react-native 一起使用吗?我也尝试过查看嵌套导航器,为我的加载页面、身份验证页面、主页等创建一个切换导航器,然后为我的身份验证页面本身创建另一个导航器(登录、注册、忘记密码),但是当尝试导航到主页,它说该导航器下不存在页面:s React-router 可以在原生 reactrouter.com/native 中使用。但正如另一位用户所建议的那样,react-navigation 可能也很合适。 【参考方案1】:虽然我建议为此使用react-navigation,但问题似乎在于您返回组件并将道具传递给它们的方式,例如Login(email, setEmail, password, setPassword, changePage, login)
应该是<Login email=email setEmail=setEmail password=password setPassword=setPassword changePage=changePage login=login/>
import React, useState from 'react';
import RootStateOrAny, useDispatch, useSelector from "react-redux";
import authForgotPassword, authLogin, authRegister from '../store/actions/authActions';
import ForgotPassword from '../components/Auth/ForgotPassword';
import Login from '../components/Auth/Login';
import PageType from '../utils/PageType';
import Register from '../components/Auth/Register';
import StackNavigationProp from '@react-navigation/stack';
type ParamList =
AuthLoadingScreen: undefined;
HomeTabScreen: undefined;
AuthScreen: undefined
type AuthScreenNavigationProp = StackNavigationProp<ParamList, 'AuthScreen'>;
type Props =
navigation: AuthScreenNavigationProp;
export default function AuthScreen( navigation : Props)
const dispatch = useDispatch();
const user = useSelector((state: RootStateOrAny) => state.auth.user);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [password2, setPassword2] = useState('');
const [showPage, setShowPage] = useState(PageType.Login);
const changePage = (pageType: PageType) =>
setEmail('');
setPassword('');
setPassword2('');
setShowPage(pageType);
const login = () =>
dispatch(authLogin(email, password));
const register = () =>
if (password === password2)
dispatch(authRegister(email, password));
else
alert('Passwords must match!');
const forgotPassword = () =>
dispatch(authForgotPassword(email, changePage));
if (user)
navigation.navigate('HomeTabScreen');
return null;
else
switch(showPage)
case PageType.Login:
return <Login email=email setEmail=setEmail password=password setPassword=setPassword changePage=changePage login=login/>
case PageType.Register:
return <Register email=email setEmail=setEmail password=password setPassword=setPassword password2=password2 setPassword2=setPassword2 changePage=changePage register=register/>
case PageType.ForgotPassword:
return <ForgotPassword email=email setEmail=setEmail changePage=changePage forgotPassword=forgotPassword/>
default: return <Login email=email setEmail=setEmail password=password setPassword=setPassword changePage=changePage login=login/>
【讨论】:
如果你必须这样做,你会怎么做?使用反应导航? 你应该问另一个问题,如果这个答案能解决你的问题,我也可以回答。 React Native 上的导航也有点复杂,因为 Tabs 和 Drawers 是不同的。 当然!我一直在盲目地盯着它,但是我怎么可能忽略了这么简单的事情……如果可以的话,我会问另一个问题并在其中标记您:) 我在这里提出了一个新问题:***.com/questions/67268327/…【参考方案2】:据我了解,登录/注册/忘记密码是功能组件。那些应该像
一样返回return <Login email=email setEmail=setEmail ... />
而不仅仅是像现在这样的普通函数调用:
return Login(email, setEmail)
如果你没有使用 jsx/tsx,那么你应该这样称呼它:
React.createElement(Login, email, setEmail, ... , ...children)
但一般来说,你为什么不直接使用 React Router 并为 Login、Register、ForgotPassword 等添加一个单独的 <Route />
而不是这个组件?那将是一个更优雅的解决方案。
【讨论】:
但是当然...?!!叹了口气,我一直盯着自己看,我怎么可能忽略了哈哈? 发生在我们最好的人身上。 :)以上是关于React Native:“渲染的钩子比预期的要少。”不知道这意味着啥,应用程序崩溃?的主要内容,如果未能解决你的问题,请参考以下文章
渲染的钩子比预期的要少。这可能是由于意外提前退货声明造成的。基于状态的条件渲染组件
react-native init 指定 react 版本和 react-native 版本
添加 React-Native-Camera 和 React-Native-Push-Notification 后无法构建 React Native
react native 增加react-native-camera