简体   繁体   English

反应: div 上的 onClick 跳转到页面顶部,而不是执行回调 function

[英]React: onClick on div jumps to top of page instead of executing callback function

I have this React application that serves as an inventory system.我有这个作为库存系统的 React 应用程序。 I have this page where there exists a plus and minus button that allows the user to increase or decrease the stock number for an individual item (it's pretty much a counter).我有这个页面,其中存在一个加号和减号按钮,允许用户增加或减少单个项目的库存编号(它几乎是一个计数器)。 So what's happening is that at first decreasing/increasing the counters for individual products were working but as my number of products, it just stopped working.所以发生的事情是,起初减少/增加单个产品的计数器是有效的,但作为我的产品数量,它只是停止工作。 When I tried to increase/decrease product, it would just jump to the top of the page.当我尝试增加/减少产品时,它只会跳到页面顶部。 After analysis, I found that I could increase/decrease stock numbers for products that were already on the page when first accessed (aka I don't need to scroll down to view them).经过分析,我发现我可以增加/减少第一次访问时已经在页面上的产品的库存数量(也就是我不需要向下滚动来查看它们)。 The ones that were not working were the ones that required some scrolling down to see them.那些不工作的是那些需要向下滚动才能看到它们的。

Here is the component (IncreaseStockItem) that renders the product name along with the plus and minus button这是呈现产品名称以及加号和减号按钮的组件 (IncreaseStockItem)

import React, { Component } from "react";

class IncreaseStockItem extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inStock: props.product.inStock,
      name: props.product.name,
      barcode: props.product.barcode,
    };
  }

  onProductIncrease = (e) => {
    e.preventDefault();
    var updatedNumber = this.state.inStock + 1;
    this.setState({ inStock: updatedNumber }, function () {
      this.handleAfterChange();
    });
  };

  onProductDecrease = (e) => {
    e.preventDefault();
    var updatedNumber = this.state.inStock - 1;
    this.setState({ inStock: updatedNumber }, function () {
      this.handleAfterChange();
    });
  };

  handleAfterChange = () => {
    this.props.onInputChange(this.state);
  };

  
  render() {
    return (
      <div className="columns">
        <div className="column is-two-thirds ml-4">
          <div className="field">
            <input className="input" value={this.state.name} readOnly></input>
          </div>
        </div>
        <div className="column">
          <span className="field">
            <div onClick={this.onProductDecrease} className="button is-danger">
              <i className="fa fa-minus"></i>
            </div>

            <input
              value={this.state.inStock}
              className="input mx-5 has-text-centered"
              type="text"
              style={{ width: "45px" }}
              readOnly
            ></input>
          </span>
          <div onClick={this.onProductIncrease} className="button is-success">
            <i className="fa fa-plus"></i>
          </div>
        </div>
      </div>
    );
  }
}

export default IncreaseStockItem;

Here is the component that renders the list of items:这是呈现项目列表的组件:

import React from "react";
import IncreaseStockItem from "./IncreaseStockItem";

const IncreaseStockProductList = ({ products, onInputChange }) => {
  const renderedList = products.map((product) => {
    return (
      <IncreaseStockItem
        key={product._id}
        product={product}
        onInputChange = {onInputChange}
      />
    );
  });

  return renderedList;
};

export default IncreaseStockProductList;

The component looks like this: Component该组件如下所示:组件

I have tried my best to describe the problem and it still might be unclear.我已尽力描述问题,但可能仍不清楚。 Let me know if you need more clarifications.如果您需要更多说明,请告诉我。

Note: The same problem happens when I use react-router Link with a link tag that's out of context.注意:当我将 react-router Link 与上下文无关的链接标签一起使用时,也会发生同样的问题。

EDIT 1:编辑1:

Whenever I zoom out so that all components are within the context of the screen (aka no need of scrolling down), everything works fine.每当我缩小以使所有组件都在屏幕的上下文中(也就是不需要向下滚动)时,一切正常。

EDIT 2:编辑2:

The component hierarchy goes like this:组件层次结构如下所示:

IncreaseStock -> IncreaseStockProductList -> IncreaseStockItem

Code for IncreaseStock below:增加库存的代码如下:

import React, { Component } from "react";
import axios from "axios";
import { withRouter } from "react-router-dom";
import Button from "./Button";
import IncreaseStockProductList from "./IncreaseStockProductList";
import Message from "./Message";
import SearchBar from "./SearchBar";

class IncreaseStock extends Component {
  constructor(props) {
    super(props);
    this.state = { products: [], updatedProducts: [] };
  }

  routingFunction = () => {
    var title = "Mises à jour du nombre de produits";
    var message =
      "Le nombre d'articles des produits suivants a été mis à jour:";

    this.props.history.push({
      pathname: "/products/",
      state: {
        title: title,
        message: message,
        products: this.state.updatedProducts,
      },
    });
  };

  onSearchBarChange = async (target) => {
    var barcode = target.value;
    axios.get("/api/products/barcode/" + barcode).then((response) => {
      if (response.data !== null) {
        this.props.history.push({
          pathname: "/products/" + barcode,
        });
      }
    });
  };

  componentDidMount() {
    axios.get("/api/products").then((response) => {
      this.setState({ products: response.data });
    });
  }

  // https://stackoverflow.com/questions/37435334/correct-way-to-push-into-state-array
  onInputChange = (data) => {
    var tempData = {
      inStock: data.inStock,
      barcode: data.barcode,
      name: data.name,
    };
    var tempArray = this.state.updatedProducts.slice();
    tempArray = tempArray.filter(function (obj) {
      return obj.barcode !== data.barcode;
    });
    tempArray.push(tempData);
    this.setState({ updatedProducts: tempArray });
  };

  onFormSubmit = (event) => {
    event.preventDefault();
    var payload = this.state.updatedProducts;
    axios({
      method: "post",
      url: "/api/products/increase",
      data: payload,
    }).then((response) => {
      this.routingFunction();
    });
  };

  render() {
    return (
      <div className="section">
        <div className="container">
          <h1 className="title has-text-centered is-size-4 mb-3">
            Modifier Votre Stock
          </h1>
          <div className="columns">
            <div className="column is-three-fifths is-offset-one-fifth">
              <Message
                products={[]}
                title="Instructions"
                type="info"
                message="Pour rechercher un produit scanner son barcode en &#233;tant sur cette page."
              />
              <SearchBar onSearchBarChange={this.onSearchBarChange} />

              <form onSubmit={this.onFormSubmit}>
                <div className="card mb-5">
                  <IncreaseStockProductList
                    products={this.state.products}
                    onInputChange={this.onInputChange}
                  />
                </div>
                <Button text="Confirmer" />
              </form>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default withRouter(IncreaseStock);

EDIT 3: Same problem with react-router-dom编辑 3: react-router-dom 有同样的问题

The same problem happens when I use react-router-dom's Link component that is out of context, clicking on the link just makes the page go to the top.当我使用脱离上下文的 react-router-dom 的链接组件时,也会发生同样的问题,单击链接只会使页面 go 到顶部。

I have a component page that lists all products inside of a table and I have a modify link that takes the user the edit page for a specific produt.我有一个组件页面,其中列出了表格内的所有产品,并且我有一个修改链接,该链接将用户带到特定产品的编辑页面。

Below is the TableCell component that displays individual cell/product.下面是显示单个单元格/产品的 TableCell 组件。

Image of TableCell TableCell 的图像

import React, {Component} from "react";
import { Link } from "react-router-dom";

class TableCell extends Component {
  constructor(props) {
    super(props);
    var notice = props.product.inStock === 0 ? "has-background-warning" : "";
    this.state = {notice:notice, id: props.product._id}
  }

  onDelete = (e) => {
    this.props.onDelete(this.props.product._id);
  }

  render() {
    return (
        <tr className={this.state.notice}>
        <td>{this.props.product.barcode}</td>
        <td>{this.props.product.name}</td>
        <td>{this.props.product.price}</td>
        <td>{this.props.product.inStock}</td>
        <td>
          <b>
            <Link
              to={{
                pathname: "/products/edit/" + this.props.product._id,
                product: this.props.product,
              }}
              className="button is-info"
            >
              Modifier
            </Link>
          </b>
        </td>
        <td>
          <b>
            <button onClick={this.onDelete} className="button is-danger has-text-white delete-button"><b>Supprimer</b></button>
          </b>
        </td>
      </tr>
    )
  }
}

export default TableCell;

You can try binding "this" to the function, maybe the render or the click its executed out of context, try with this:您可以尝试将“this”绑定到 function,可能是渲染或单击其执行脱离上下文,试试这个:

onClick={this.onProductIncrease.bind(this)}

as tip, inquire about, execution context in javascript, and go to reacts official documentation作为提示,查询 javascript 和 go 中的执行上下文以响应官方文档

Is there any output in the console when you try to fire the function?当您尝试触发 function 时,控制台中是否有任何 output? Try adding a console.log in the onProductIncrease function to see if it is firing properly.尝试在 onProductIncrease function 中添加一个 console.log 以查看它是否正常触发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM