最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - useState and callback function - Stack Overflow

programmeradmin7浏览0评论

In the class ponent, the setState() method can take a callback function, but in a functional ponent when I give a callback to costume setState this warning occurs: Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the ponent body with useEffect(). I need my state set, and then the page will redirect. But I don't have any idea.

In the class ponent, the setState() method can take a callback function, but in a functional ponent when I give a callback to costume setState this warning occurs: Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument. To execute a side effect after rendering, declare it in the ponent body with useEffect(). I need my state set, and then the page will redirect. But I don't have any idea.

Share Improve this question edited Nov 7, 2021 at 7:36 S. Hesam asked Nov 27, 2019 at 7:33 S. HesamS. Hesam 6,6535 gold badges45 silver badges64 bronze badges 6
  • 2 The warning you are getting there is trying to give you the idea actually. You can use useEffect for this. – devserkan Commented Nov 27, 2019 at 7:39
  • 1 Hi, if you would like a more explicit answer feel free to share any code that is troubling you and we will be able to help better – JamesGill Commented Nov 27, 2019 at 7:43
  • What if your functional ponent remain class ponent? is there any special concern for that? – tareq aziz Commented Nov 27, 2019 at 7:43
  • @devserkan How can I useEffect for this situation? – S. Hesam Commented Nov 27, 2019 at 7:44
  • @tareqaziz I have to use functional ponents. – S. Hesam Commented Nov 27, 2019 at 7:46
 |  Show 1 more ment

2 Answers 2

Reset to default 15

Instead of passing a callback function, use useEffect hook, and do something like this to achieve the desired result.

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

Be careful! In a class ponent, you can call a callback function right after each setState that you want, but in the functional ponent, the useEffect hook run after any changing state that happens in the whole of your ponent. To handle this challenge, you should be careful in choosing your state and how to set it.

This is a very simple example:

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

In class ponent:

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>
    );
  }
}
发布评论

评论列表(0)

  1. 暂无评论