当前位置: 首页 > 面试题库 >

您可以使用React钩子早日返回吗?

潘兴朝
2023-03-14
问题内容

React文档明确指出,有条件地调用钩子是行不通的。从原始的React
hooks演示文稿来看
,原因是因为React使用您调用hook的顺序来注入正确的值。

我理解这一点,但是现在我的问题是,从带有钩子的函数组件中尽早返回是否可以?

那么允许这样的事情吗?

import React from 'react';
import { useRouteMatch, Redirect } from 'react-router';
import { useSelector } from 'react-redux';

export default function Component() {
  const { match } = useRouteMatch({ path: '/:some/:thing' });
  if (!match) return <Redirect to="/" />;

  const { some, thing } = match.params;
  const state = useSelector(stateSelector(some, thing));

  return <Blah {...state} />;
}

从技术上讲,该useSelector挂钩是有条件地调用的,但是在渲染之间它们的调用顺序不会改变(即使有可能会调用更少的挂钩)。

如果不允许这样做,您能否解释 为什么 不允许这样做,并提供通用的替代方法来尽早返回带有钩子的函数组件?


问题答案:

React不允许您在其他钩子之前先返回。如果一个组件执行的钩子少于以前的渲染,则将出现以下错误:

不变违规:渲染的钩子少于预期。这可能是由意外的提前归还声明引起的。

React无法分辨早期返回和条件挂钩调用之间的区别。例如,如果您有3个呼叫,useState而您有时在第二个useState呼叫之后返回,则React无法告知您是在第二个呼叫之后返回还是在第一个或第二个useState呼叫周围设置了条件,因此它无法可靠地知道它是否是两个返回正确的状态useState的呼叫
没有 发生。

这是一个示例,您可以用来查看此错误的实际发生(两次单击“增量状态1”按钮以获取错误):

import React from "react";
import ReactDOM from "react-dom";

function App() {
  const [state1, setState1] = React.useState(1);
  if (state1 === 3) {
    return <div>State 1 is 3</div>;
  }
  const [state2, setState2] = React.useState(2);
  return (
    <div className="App">
      <div>State 1: {state1}</div>
      <div>State 2: {state2}</div>
      <button onClick={() => setState1(state1 + 1)}>Increment State 1</button>
      <button onClick={() => setState2(state2 + 1)}>Increment State 2</button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

我建议的另一种方法是将早期返回的部分分成自己的部分。提早返回后该部分所需的任何内容都将作为道具传递给新组件。

以我的示例为例,它可能如下所示:

import React from "react";
import ReactDOM from "react-dom";

const AfterEarlyReturn = ({ state1, setState1 }) => {
  const [state2, setState2] = React.useState(2);
  return (
    <div className="App">
      <div>State 1: {state1}</div>
      <div>State 2: {state2}</div>
      <button onClick={() => setState1(state1 + 1)}>Increment State 1</button>
      <button onClick={() => setState2(state2 + 1)}>Increment State 2</button>
    </div>
  );
};
function App() {
  const [state1, setState1] = React.useState(1);
  if (state1 === 3) {
    return <div>State 1 is 3</div>;
  }
  return <AfterEarlyReturn state1={state1} setState1={setState1} />;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);



 类似资料:
  • 我通常使用getBoundingClientRect()。宽度当开发一个Swiper组件使用反应挂钩,但在一些例子getBoundingClientRect()。宽度返回0。 我在useEffect函数中使用了setTimeout,效果很好; 下面是简单的swiper代码演示: 简单swiper演示代码

  • 我遇到一个问题,React路由器无法使用hook获取参数。当转到路由时,(浏览器路径包括basename),控制台.log()在这里记录一个空对象,,它应该在这里显示例如 看看这个例子https://reacttraining.com/react-router/web/api/Hooks/useparams 这应该行得通。

  • 问题内容: React钩子介绍了用于设置组件状态的方法。但是我如何使用钩子来代替如下代码的回调: 我想在状态更新后做一些事情。 我知道我可以用来做其他事情,但是我必须检查状态以前的值,这需要一个位代码。我正在寻找可以与钩子一起使用的简单解决方案。 问题答案: 您需要使用钩子来实现此目的。

  • React hooks引入了来设置组件状态。但是我如何使用钩子来替换回调,如下代码所示:

  • 我发现有几种方法可以用钩子处理用户的文本输入。用钩子处理输入的更好或更合适的方法是什么?你会用哪一种? 1)处理输入的最简单的钩子,但是你有更多的字段,你必须写更多重复的代码。 活动: 2) 与上面的示例类似,但具有动态键名 活动: 3) 作为的替代方案,正如ReactJS文档中所述,通常比更可取。 活动: 4) 将返回一个回调的备忘录版本,该版本仅在其中一个依赖项发生更改时才会更改。 活动:

  • 当类组件的输入道具相同时,可以使用PureComponent或ShouldComponentUpdate来避免呈现。现在,您可以通过将函数组件包装在react.memo中来对它们进行同样的处理。 所期望的: 我希望只有当模态可见时才呈现模态(由this.props.show管理) 对于类组件: 如何在功能组件中使用?在modal.jsx中? 相关代码: 功能组件modal.jsx(我不知道如何检查