标签: react-hooks

在使用挂钩时,React是否批量状态更新功能?

对于类组件,this.setState如果在事件处理程序内部则调用批处理.但是如果在事件处理程序之外更新状态并使用'useState'钩子会发生什么?

function Component() {
  const [a, setA] = useState('a');
  const [b, setB] = useState('b');

  function handleClick() {
    Promise.resolve().then(() => {
      setA('aa');
      setB('bb');
    });
  }

  return <button onClick={handleClick}>{a}-{b}</button>
}
Run Code Online (Sandbox Code Playgroud)

它会useState马上渲染吗?或者它会是aa - bb然后aa - b呢?

reactjs react-hooks

28
推荐指数
4
解决办法
4663
查看次数

使用useEffect,如何跳过对初始渲染应用效果?

使用React的新效果钩子,如果重新渲染之间某些值没有改变,我可以告诉React跳过应用效果 - 来自React的文档示例:

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // Only re-run the effect if count changes
Run Code Online (Sandbox Code Playgroud)

但是上面的例子应用了初始渲染时的效果,以及后续重新渲染的位置count.如何告诉React跳过初始渲染的效果?

reactjs react-hooks

28
推荐指数
7
解决办法
1万
查看次数

我在哪里可以使用钩子进行API调用?

基本上我们componentDidMount()在React类组件中的生命周期方法中进行API调用,如下所示

     componentDidMount(){
          //Here we do API call and do setState accordingly
     }
Run Code Online (Sandbox Code Playgroud)

但是在React v16.7.0中引入了钩子之后,就没有更多的类组件了.

我的查询是,我们究竟需要在带有钩子的功能组件中进行API调用?

我们有类似的方法componentDidMount()吗?

javascript reactjs react-native react-hooks

28
推荐指数
3
解决办法
1万
查看次数

反应挂钩useEffect依赖数组

我试图把头缠在新的react钩子api上。具体来说,我正在尝试构建一次经典的用例:

componentDidUpdate(prevProps) {
    if (prevProps.foo !== this.props.foo) {
        // animate dom elements here...
        this.animateSomething(this.ref, this.props.onAnimationComplete);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我尝试使用功能组件和构建相同的组件useEffect,但不知道如何实现。这是我尝试的:

useEffect(() => {
    animateSomething(ref, props.onAnimationComplete);
}, [props.foo]);
Run Code Online (Sandbox Code Playgroud)

这样,仅在props.foo更改时才调用效果。那确实有效–但是!由于将其eslint-plugin-react-hooks标记为错误,因此它似乎是反模式。效果内使用的所有依赖项都应在依赖项数组中声明。因此,这意味着我必须执行以下操作:

useEffect(() => {
    animateSomething(ref, props.onAnimationComplete);
}, [props.foo, ref, props.onAnimationComplete]);
Run Code Online (Sandbox Code Playgroud)

但这不会导致掉毛错误,但完全无法实现props.foo更改时调用效果的目的。我不希望在其他道具或裁判改变时调用它。

现在,我读到一些有关使用useCallback这种包装的信息。我试过了,但没有得到进一步的解决。

有人可以帮忙吗?

javascript reactjs react-hooks

28
推荐指数
1
解决办法
1万
查看次数

未找到规则“re​​act-hooks/exhaustive-deps”的定义

添加// eslint-disable-next-line react-hooks/exhaustive-deps我的代码后,我收到以下 eslint 错误。

8:14 未找到规则“re​​act-hooks/exhaustive-deps”的错误定义

我参考了这篇文章来解决这个问题,但提到的解决方案在我的情况下不起作用。任何线索如何抑制这个eslint错误?

PS我结合使用standardjs

javascript reactjs eslint standardjs react-hooks

28
推荐指数
4
解决办法
1万
查看次数

如何模拟反应自定义钩子返回值?

这是我的自定义钩子:

  export function useClientRect() {
    const [scrollH, setScrollH] = useState(0);
    const [clientH, setClientH] = useState(0);
    const ref = useCallback(node => {
      if (node !== null) {
        setScrollH(node.scrollHeight);
        setClientH(node.clientHeight);
      }
    }, []);
    return [scrollH, clientH, ref];
  }
}
Run Code Online (Sandbox Code Playgroud)

我希望每次调用它时,它都会返回我的值。喜欢:

jest.mock('useClientRect', () => [300, 200, () => {}]);
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

reactjs jestjs react-testing-library react-hooks

28
推荐指数
3
解决办法
3万
查看次数

函数式组件:在组件内部还是外部编写函数?

我经常按照“类架构”编写功能组件,其中所有与组件相关的函数都像类中的方法一样写在其中。

例如,我这里有一个counterAsFloatCounter组件相关的函数。如您所见,我只是在组件内部编写了它:

export default function Counter() {
  const [counter, setCounter] = React.useState(0);

  const counterAsFloat = () => {
    return counter.toFixed(2);
  };

  return (
    <div className="counter">
      <h1>{counterAsFloat()}</h1>
      <button onClick={() => setCounter(counter + 1)}>
        Increment
      </button>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

但实际上我也可以只在组件外部声明函数并使用它的参数:

const counterAsFloat = (counter) => { 
  return counter.toFixed(2);
};

export default function Counter() {
  const [counter, setCounter] = React.useState(0);

  return (
    <div className="counter">
      <h1>{counterAsFloat(counter)}</h1>
      <button onClick={() => setCounter(counter + 1)}>
        Increment
      </button>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

那么在功能组件之外编写函数有什么好处或坏处吗?

javascript reactjs react-hooks

28
推荐指数
1
解决办法
5711
查看次数

使用React钩子等同于componentDidUpdate

tldr; 如何模拟componentDidUpdate或以其他方式使用key数组来强制重置组件?

我正在实现一个显示计时器的组件,并在达到零时执行回调.目的是让回调更新对象列表.后一个组件由新的React钩子 useStateuseEffect.

state包含对计时器启动时间和剩余时间的引用.该effect套间隔称为每秒钟更新的剩余时间,并检查是否回调应该叫.

该组件并不意味着重新安排定时器,或者当它达到零时保持间隔,它应该执行回调和空闲.为了让计时器刷新,我希望传递一个数组,key这将导致组件的状态被重置,因此计时器将重新启动.不幸的是key必须与字符串一起使用,因此我的数组的引用是否已更改不会产生任何影响.

我还试图通过传递我关注的数组来推动对道具的更改,但状态得到维护,因此间隔未重置.

为了强制仅使用新的钩子API更新状态,在数组中观察浅层更改的首选方法是什么?

import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';

function getTimeRemaining(startedAt, delay) {
    const now = new Date();
    const end = new Date(startedAt.getTime() + delay);
    return Math.max(0, end.getTime() - now.getTime());
}

function RefresherTimer(props) {
    const [startedAt, setStartedAt] = useState(new Date());
    const [timeRemaining, setTimeRemaining] = useState(getTimeRemaining(startedAt, props.delay));

    useEffect(() => {

        if (timeRemaining <= 0) …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-hooks

27
推荐指数
3
解决办法
2万
查看次数

useSelector 破坏与多次调用

最近我正在阅读 react-redux 文档https://react-redux.js.org/next/api/hooks 并且有一个与平等比较和更新相关的部分,它说:

多次调用 useSelector(),每次调用返回一个字段值。

第一种方法:

const { open, importId, importProgress } = useSelector((importApp) => importApp.productsImport);
Run Code Online (Sandbox Code Playgroud)

第二种方法:

const open = useSelector((importApp) => importApp.productsImport.open);
const importId = useSelector((importApp) => importApp.productsImport.importId );
const importProgress = useSelector((importApp) => importApp.productsImport.importProgress);
Run Code Online (Sandbox Code Playgroud)

那么有什么真正的区别吗?或者由于破坏 useSelector 钩子会在检查引用时遇到麻烦?

reactjs react-redux react-hooks

27
推荐指数
4
解决办法
8502
查看次数

将数组传递给 useEffect 依赖列表

有一些数据来自每 5 秒的长轮询,我希望我的组件在每次数组的一项(或数组长度本身)发生变化时分派一个动作。在将数组作为依赖项传递给 useEffect 时,如何防止 useEffect 进入无限循环,但如果任何值发生更改,仍然设法调度某些操作?

useEffect(() => {
  console.log(outcomes)
}, [outcomes])
Run Code Online (Sandbox Code Playgroud)

其中outcomes是一组 ID,例如[123, 234, 3212]. 数组中的项目可能会被替换或删除,因此数组的总长度可能 - 但不必 - 保持不变,因此outcomes.length作为依赖传递不是这种情况。

outcomes 来自 reselect 的自定义选择器:

const getOutcomes = createSelector(
  someData,
  data => data.map(({ outcomeId }) => outcomeId)
)
Run Code Online (Sandbox Code Playgroud)

reactjs react-hooks

27
推荐指数
3
解决办法
2万
查看次数