【问题标题】:Cannot redirect one page to another page in ReactJs无法将一个页面重定向到 ReactJs 中的另一个页面
【发布时间】:2022-01-04 04:48:56
【问题描述】:

我正在制作一个功能,当我单击图像容器时,它将打开带有产品详细信息的页面,其中包含每个特定产品的确切详细信息。但是,当我单击图像时,什么也没有发生!请帮我找出我的代码有什么问题,非常感谢!

Product.js:

class Product extends React.Component {
  render() {
    const { id, title, img, price, inCart } = this.props.product;
    return (
      <ProductWrapper clasName="col-9 mx-auto col-md-6 col-lg-3 my-3">
        <div className="card">
          <ProductContext.Consumer>
            {(value) => (
              <div className="img-container p-5">
                <Router>
                  <Link to="/details">
                    <img
                      src={img}
                      alt="product"
                      className="card-img-top"
                      onClick={() => {
                        value.handleDetail(id);
                      }}
                    />
                  </Link>
                </Router>
                <button
                  className="cart-btn"
                  onClick={() => value.addToCart(id)}
                  disabled={inCart ? true : false}
                >
                  {inCart ? (
                    <p className="text-capitalize mb-0">In Cart</p>
                  ) : (
                    <i class="fas fa-cart-plus"></i>
                  )}
                </button>
              </div>
            )}
          </ProductContext.Consumer>
          <div className="card-footer d-flex justify-content-between">
            <p className="align-self-center mb-0">{title}</p>
            <h5 className="text-blue mb-0">
              <span className="mr-1">$</span>
              {price}
            </h5>
          </div>
        </div>
      </ProductWrapper>
    );
  }
}

context.js:

class ProductProvider extends React.Component {
  state = {
    products: storeProducts,
    detailProduct: detailProduct
  };

  getItem = (id) => {
    const product = this.state.products.find((item) => item.id === id);
    return product;
  };

  handleDetail = (id) => {
    const product = this.getItem(id);
    this.setState(() => {
      return { detailProduct: product };
    });
  };
  addToCart = (id) => {
    console.log(`hello details. id is ${id}`);
  };
  render() {
    return (
      <ProductContext.Provider
        value={{
          ...this.state,
          handleDetail: this.handleDetail,
          addToCart: this.addToCart
        }}
      >
        {this.props.children}
      </ProductContext.Provider>
    );
  }
}

沙盒链接以便更好地观察:https://codesandbox.io/s/why-cant-i-fetch-data-from-a-passed-value-forked-30bgi?file=/src/App.js

【问题讨论】:

    标签: reactjs hyperlink


    【解决方案1】:

    我推荐一种不同的方法,将产品 ID 放入 URL 中,而不是在上下文中选择。这样做的主要优势在于刷新详情页面意味着产品 ID 将被保留。

    这是a working CodeSandbox的链接。

    以下是我所做的更改:

    1. 在上下文提供程序中,您可以删除 handleDetail,因为选择将改为存在于 URL 中:
    class ProductProvider extends React.Component {
      state = {
        products: storeProducts,
        detailProduct: detailProduct
      };
    
      getItem = (id) => {
        const product = this.state.products.find((item) => item.id === id);
        return product;
      };
    
      addToCart = (id) => {
        console.log(`hello details. id is ${id}`);
      };
      render() {
        return (
          <ProductContext.Provider
            value={{
              ...this.state,
              addToCart: this.addToCart
            }}
          >
            {this.props.children}
          </ProductContext.Provider>
        );
      }
    }
    
    1. 在App 组件中,将details 路由更改为采用itemId 参数:
    export default function App() {
      return (
        <div className="App">
          <h1>Hello CodeSandbox</h1>
          <h2>Start editing to see some magic happen!</h2>
    
          <ProductProvider>
            <Router>
              <Switch>
                <Route exact path="/productlist" component={ProductList} />
                <Route path="/details/:itemId" component={Details} />
                <Route path="*" component={() => "404 Not Found"} />
              </Switch>
            </Router>
          </ProductProvider>
        </div>
      );
    }
    
    1. 在您的产品组件中,使 Link 指向 details/itemId URL,并消除在上下文中设置该 ID 的任何需要:
    class Product extends React.Component {
      render() {
        const { id, title, img, price, inCart } = this.props.product;
        return (
          <ProductWrapper clasName="col-9 mx-auto col-md-6 col-lg-3 my-3">
            <div className="card">
              <ProductContext.Consumer>
                {(value) => (
                  <div className="img-container p-5">
                    <Link to={`/details/${id}`}>
                      <img src={img} alt="product" className="card-img-top" />
                    </Link>
                    <button
                      className="cart-btn"
                      onClick={() => value.addToCart(id)}
                      disabled={inCart ? true : false}
                    >
                      {inCart ? (
                        <p className="text-capitalize mb-0">In Cart</p>
                      ) : (
                        <i class="fas fa-cart-plus"></i>
                      )}
                    </button>
                  </div>
                )}
              </ProductContext.Consumer>
              <div className="card-footer d-flex justify-content-between">
                <p className="align-self-center mb-0">{title}</p>
                <h5 className="text-blue mb-0">
                  <span className="mr-1">$</span>
                  {price}
                </h5>
              </div>
            </div>
          </ProductWrapper>
        );
      }
    }
    
    1. 最后,在Details 组件中,从参数中取出itemId 并从上下文中的产品列表中取出find 正确的项目:
    class Details extends React.Component {
      render() {
        const { itemId } = this.props.match.params;
    
        return (
          <ProductContext.Consumer>
            {(value) => {
              const selected = value.products.find(
                (p) => p.id === parseInt(itemId)
              );
    
              if (!selected) {
                return "Bad product ID: " + itemId;
              }
    
              const { id, company, img, info, price, title, inCart } = selected;
    
              return (
                <div className="container py-5">
                  {/* title */}
                  <div className="row">
                    <div className="col-10 mx-auto text-center text-slanted text-blue my-5">
                      <h1>{title}</h1>
                    </div>
                  </div>
                  {/* end of title */}
                  <div className="row">
                    <div className="col-10 mx-auto col-md-6 my-3">
                      <img src={img} className="img-fluid" alt="" />
                    </div>
                    {/* prdoduct info */}
                    <div className="col-10 mx-auto col-md-6 my-3 text-capitalize">
                      <h1>model : {title}</h1>
                      <h4 className="text-title text-uppercase text-muted mt-3 mb-2">
                        made by : <span className="text-uppercase">{company}</span>
                      </h4>
                      <h4 className="text-blue">
                        <strong>
                          price : <span>$</span>
                          {price}
                        </strong>
                      </h4>
                      <p className="text-capitalize font-weight-bold mt-3 mb-0">
                        some info about product :
                      </p>
                      <p className="text-muted lead">{info}</p>
                      {/* buttons */}
                      <div>
                        <Link to="/productlist">
                          <ButtonContainer>back to products</ButtonContainer>
                        </Link>
                        <ButtonContainer
                          cart
                          disabled={inCart ? true : false}
                          onClick={() => {
                            value.addToCart(id);
                          }}
                        >
                          {inCart ? "in cart" : "add to cart"}
                        </ButtonContainer>
                      </div>
                    </div>
                  </div>
                </div>
              );
            }}
          </ProductContext.Consumer>
        );
      }
    }
    

    【讨论】:

    • 好吧,我真的不明白这一行的作用“ const { itemId } = this.props.match.params;” .你能解释一下吗?
    • 这是解构赋值。和 const itemId = this.props.match.params.itemId 基本一样。那是路由器将放置任何 url 参数的 React props 中的位置。
    • 当然!如果此答案对您有用,请将其标记为解决方案
    猜你喜欢
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 2015-04-24
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    相关资源
    最近更新 更多