反应useEffect钩子循环,依赖问题

时间:2020-04-25 22:07:52

标签: reactjs react-hooks

效果最终以无休止的重新渲染循环结束,它不断向URL发出请求。基本上,我拥有的是用于获取国家/地区的API调用。然后根据过滤器输入,呈现与搜索匹配的国家。如果只有一个结果,它还应该获取并显示首都的天气信息。

我唯一想重新渲染天气的时间是当国家/地区的值更改时。不知何故我无法正常工作。.

    import javafx.application.Application;
    import javafx.geometry.Point2D;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Arc;
    import javafx.scene.shape.ArcType;
    import javafx.stage.Stage;

    public class Example extends Application {

        private  Arc arc1, arc2;
        private StackPane root;

      @Override
      public void start(Stage primaryStage) {
          arc1 = getArc(200, 200, 200, 200, 90, 90, "arc1");
          arc2 = getArc(0, 200, 200, 200, 0, 90, "arc2");
          root = new StackPane(arc1, arc2);
          root.setOnMouseClicked(event -> onStackPaneClick(event.getX(), event.getY()));
          Scene scene = new Scene(root, 200, 200);
          primaryStage.setScene(scene);
          primaryStage.show();
      }

      private Arc getArc(double x, double y,  double radiusX, double radiusY, double startAngle, double endAngle, String userData){    
          Arc arc = new Arc(x,y, radiusX,radiusY,startAngle, endAngle);
          arc.setStroke(Color.BLACK);
          arc.setFill(Color.TRANSPARENT);
          arc.setStrokeWidth(10);
          arc.setType(ArcType.OPEN);
          arc.setPickOnBounds(false);
          arc.setUserData(userData);
          return arc;
      }

      private void onStackPaneClick(double x, double y) {
        for (Node itNode : root.getChildren()) {
            if (itNode.contains(new Point2D(x, y))) {
                if (itNode instanceof Arc) {
                    Arc itArc = (Arc) itNode;
                    double centerDistance = Math.sqrt(
                            (x - itArc.getCenterX()) * (x - itArc.getCenterX()) +
                            (y - itArc.getCenterY()) * (y - itArc.getCenterY()));
                    if (centerDistance >= itArc.getRadiusX() - itArc.getStrokeWidth() / 2) {
                        System.out.println(itArc.getUserData());
                        break;
                    }
                }
            }
        }
      }

      public static void main(String[] args) {
          launch(args);
      }
    }

1 个答案:

答案 0 :(得分:1)

无论何时呈现组件,都将重新创建filtered(依赖项),这意味着将调用useEffect,使API全部设置,从而设置状态并导致重新渲染,从而重新创建{{1 }} ...

为防止这种情况,请用filteredfiltered表达式包装起来。 useMemo块应取决于useMemocountries。只要filtercountries不变,filter就会保持不变,从而防止循环。如果其中之一发生更改,filtered将会发生更改,并且filtered将使用新数据再次调用API。

useEffect

另一种选择是使用let filtered = useMemo(() => countries.filter(country => country.name.toUpperCase().includes(filter.toUpperCase()), [countries, filter]) 代替过滤器,并使Array.find()依赖于找到的国家/地区:

useEffect()