useState 和回调函数

Posted

技术标签:

【中文标题】useState 和回调函数【英文标题】:useState and callback function 【发布时间】:2020-03-22 17:06:35 【问题描述】:

在类组件中,setState() 方法可以采用回调函数,但在功能组件中,当我给服装 setState 回调时,会出现此警告: 警告:来自useState()useReducer() 钩子的状态更新不支持第二个回调参数。要在渲染后执行副作用,请在组件主体中使用useEffect() 声明它。 我需要我的状态集,然后页面将重定向。但我不知道。

【问题讨论】:

你到达那里的警告实际上是试图给你这个想法。您可以为此使用useEffect 您好,如果您想要更明确的答案,请随时分享任何困扰您的代码,我们将能够提供更好的帮助 如果你的功能组件仍然是类组件怎么办?有什么特别担心的吗? @devserkan 这种情况如何使用Effect? @tareqaziz 我必须使用功能组件。 【参考方案1】:

小心!在类组件中,您可以在您想要的每个 setState 之后调用回调函数,但在功能组件中,useEffect 挂钩在整个组件中发生的任何更改您的状态之后运行。 为了应对这一挑战,您应该谨慎选择您的状态以及如何设置它。

This 是一个非常简单的例子:

import  Grid, Button, Typography  from "@material-ui/core";
import  Component, useState, useEffect  from "react";

export const FunctionComponent = () => 
  const [count, setCount] = useState(0);
  const [background, setBackground] = useState("white");

  useEffect(() => 
    setTimeout(() => setBackground("white"), 100);
  , [background]);

  const countIncreamentHandler = () => 
    setCount((count) => count + 1);
    setBackground("rgba(112, 181, 0, .2)");
  ;
  const countDecreamentHandler = () => 
    setCount((count) => count - 1);
    setBackground("rgba(181, 9, 0, .2)");
  ;

  return (
    <Grid container justify="space-around">
      <Button
        variant="contained"
        color="primary"
        onClick=countIncreamentHandler
      >
        +
      </Button>
      <Typography style= padding: 5, background  variant="h5">
        count
      </Typography>
      <Button
        variant="contained"
        color="secondary"
        onClick=countDecreamentHandler
      >
        -
      </Button>
    </Grid>
  );
;

export class ClassCompontet extends Component 
  constructor() 
    super();
    this.state = 
      count: 0,
      background: "white"
    ;
  

  countIncreamentHandler = () => 
    this.setState(
      (prevState) => (
        count: prevState.count + 1,
        background: "rgba(112, 181, 0, .2)"
      ),
      () => 
        setTimeout(() => 
          this.setState( background: "white" );
        , 100);
      
    );
  ;
  countDecreamentHandler = () => 
    this.setState(
      (prevState) => (
        count: prevState.count - 1,
        background: "rgba(181, 9, 0, .2)"
      ),
      () => 
        setTimeout(() => 
          this.setState( background: "white" );
        , 100);
      
    );
  ;

  render() 
    return (
      <Grid container justify="space-around">
        <Button
          variant="contained"
          color="primary"
          onClick=this.countIncreamentHandler
        >
          +
        </Button>
        <Typography
          style= padding: 5, background: this?.state?.background 
          variant="h5"
        >
          this?.state?.count
        </Typography>
        <Button
          variant="contained"
          color="secondary"
          onClick=this.countDecreamentHandler
        >
          -
        </Button>
      </Grid>
    );
  

【讨论】:

【参考方案2】:

不要传递callback 函数,而是使用useEffect 钩子,做一些这样的事情来达到预期的结果。

 useEffect(() => 
    console.log('state changed', your-state-variable)
    // write your callback function here
  , [your-state-variable]);

【讨论】:

以上是关于useState 和回调函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在反应中使用带有useState钩子的回调[重复]

带有回调的 React Hooks useState [重复]

不能在回调中调用 React Hook “useState”

useReducer 和 useState

提交值时如何在 React 挂钩中使用回调函数?

从带有回调的 this.setState 调用迁移到 useState 和 useEffect