Реакция: onClick на div переходит в начало страницы вместо выполнения функции обратного вызова - PullRequest
0 голосов
/ 06 августа 2020

У меня есть приложение React, которое служит системой инвентаризации. У меня есть эта страница, где есть кнопка «плюс» и «минус», которая позволяет пользователю увеличивать или уменьшать количество запасов для отдельного предмета (это почти счетчик). Итак, что происходит, так это то, что сначала уменьшение / увеличение счетчиков для отдельных продуктов работало, но из-за моего количества продуктов оно просто перестало работать. Когда я пытался увеличить / уменьшить продукт, он просто переходил в верхнюю часть страницы. После анализа я обнаружил, что могу увеличивать / уменьшать количество товаров, которые уже были на странице при первом доступе (также как мне не нужно прокручивать вниз, чтобы просмотреть их). Не работали те, которые требовали прокрутки вниз, чтобы увидеть их.

Вот компонент (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;

Вот компонент, который отображает список элементов:

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;

Компонент выглядит так: Компонент

Я изо всех сил старался описать проблему и это все еще может быть неясным. Дайте мне знать, если вам нужны дополнительные пояснения.

Примечание. Та же проблема возникает, когда я использую ссылку «реакция-маршрутизатор» с тегом ссылки, который находится вне контекста.

ИЗМЕНИТЬ 1:

Всякий раз, когда я уменьшаю масштаб так, чтобы все компоненты находились в контексте экрана (иначе говоря, нет необходимости прокручивать вниз), все работает нормально.

EDIT 2:

Иерархия компонентов выглядит следующим образом:

IncreaseStock -> IncreaseStockProductList -> IncreaseStockItem

Код для IncreaseStock ниже:

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: Та же проблема с реакцией -router-dom

Та же проблема возникает, когда я использую компонент Link response-router-dom, который находится вне контекста, нажатие на ссылку просто переводит страницу go наверх.

У меня есть страница компонента, на которой перечислены все продукты внутри таблицы, и у меня есть ссылка для изменения, которая переводит пользователя на страницу редактирования для c продукта.

Ниже представлен компонент TableCell, который отображает отдельную ячейку /product.

Изображение 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;

Ответы [ 2 ]

0 голосов
/ 07 августа 2020

Есть ли какой-либо вывод в консоли, когда вы пытаетесь запустить функцию? Попробуйте добавить console.log в функцию onProductIncrease, чтобы проверить, не срабатывает ли он.

0 голосов
/ 06 августа 2020

Вы можете попробовать привязать "this" к функции, может быть, рендеринг или щелчок по нему выполняется вне контекста, попробуйте с этим:

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

в качестве подсказки, узнать о контексте выполнения в javascript и go для реагирования на официальную документацию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...