首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在ReactJS上的不同组件之间更新状态

在ReactJS上的不同组件之间更新状态
EN

Stack Overflow用户
提问于 2019-05-21 02:24:22
回答 3查看 87关注 0票数 0

我正在尝试将状态从另一个组件更新到另一个组件。

我希望在header.jsx上单击product.jsx上的add to cart按钮时更新状态和总购物车

以下是我的代码

index.jsx

代码语言:javascript
复制
  import React from 'react';
    import { render } from 'react-dom';
    import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

    import Header from './header';
    import Footer from './footer';
    import Posts from './posts';
    import Post from './post';
    import Products from './products';
    import Product from './product';
    import Page from './page';

    // Load the Sass file

    require('./style.scss');
    const App = () => (
        <div id="page-inner">
            <Header />
            <main id="content">
                <Switch>

                    <Route exact path={Settings.path + 'products/:product'} component={Product} />

                </Switch>
            </main>
            <Footer />
        </div>
    );

    // Routes
    const routes = (
        <Router>
            <Route path="/" component={App} />
        </Router>
    );

    render(
        (routes), document.getElementById('page')
    );

header.jsx

代码语言:javascript
复制
import React from "react";
import { Link } from "react-router-dom";

class Header extends React.Component {
constructor(props) {
        super(props);
        this.state = { products: [], total: 0 }
        var total = 0;
    this.cartUpdated = this.cartUpdated.bind(this)


      }

      componentDidMount() {

        //let cart = localStorage.getItem('total');
              //   this.setState({  total: 100  });



      }
      cartUpdated()
      {
                 this.setState({  total: cart+100  });


      }




render() {
    return (

          <div className="cart-icon p-3 m-auto">
            Cart/ Total: <span className=""><span className="cart">€</span>{this.state.total}</span><i className="fas fa-shopping-cart" />
          </div>

    );
  }
  }

export default Header;

product.jsx

代码语言:javascript
复制
import React from "react";
import NotFound from "./not-found";

import "react-image-gallery/styles/scss/image-gallery.scss";
import ImageGallery from 'react-image-gallery';



class Product extends React.Component {





  constructor(props) {
    super(props);
    this.state = { product: {},  total: 0
};

    // ACTIONS
// addToCart
     this.addToCart = this.addToCart.bind(this);





  }
  addToCart() 
  {
        this.props.cartUpdated;

     /*
        let total = localStorage.getItem('total') 
                      ? JSON.parse(localStorage.getItem('total')) : {};

        localStorage.setItem('total', 100); */

  }



  componentDidMount() {


          this.fetchData();


  }

  fetchData = () => {
    .......
  };

  renderProduct() {
     if (this.state.product.images) {
 const images = [];
 if (this.state.product) {

   this.state.product.images.map((image, i) => {  
    var new_image = {"original":image, "thumbnail":image}  ; 
          images.push(new_image);
        });
 }




    return (

      <div className="col-md-12">
      <div className="row">
        <div className="col-md-6">
              <ImageGallery items={images} showPlayButton={false} showFullscreenButton={false} thumbnailPosition="left" />
           </div>
                <div className="col-md-6">
                <h4 className="card-title">{this.state.product.name}</h4>
            <p className="card-text">
              <strike>${this.state.product.regular_price}</strike>{" "}
              <u>${this.state.product.sale_price}</u>
            </p>
            <p className="card-text">
              <small className="text-muted">
                {this.state.product.stock_quantity} in stock
              </small>
            </p>
            <p
              className="card-text"
              dangerouslySetInnerHTML={{
                __html: this.state.product.description
              }}
            />
            <div className="superflex add_to_cart_wrapper">
  <button type="submit" name="add-to-cart" value={93} className="add_to_cart btn btn-success alt" onClick={this.props.cartUpdated}>Add to cart</button>
</div>
</div>
</div>
      </div>
    );
  }
  }

  renderEmpty() {
    return <NotFound />;
  }

  render() {
    return (
      <div className="container post-entry">
        {this.state.product ? this.renderProduct() : this.renderEmpty()}
      </div>
    );
  }





}

export default Product;
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-05-21 03:26:26

您可以这样做来实现这一点。但React JS建议的更简洁的解决方案是使用React上下文API。

我分享了一个来自React JS文档的链接,它与你想要处理的场景完全相同。

https://reactjs.org/docs/context.html#updating-context-from-a-nested-component

另外,由于您使用的是React纯组件函数,因此我们可以使用React挂钩,您可以在这里查看

https://reactjs.org/docs/hooks-reference.html#usestate

所以在你的代码中应该是这样的

代码语言:javascript
复制
./Total-Context.js

export const TotalContext = React.createContext({
  total: 0,
  setTotal: () => {

  },
});
代码语言:javascript
复制
./index.jsx

import { TotalContext } from './Total-Context';

const App = () => {
  const [total, setTotal] = useState(0);

  return (
    <TotalContext.Provider value={{total, setTotal}}>
      <div id="page-inner">
        <Header currentTotal={total} />
        <main id="content">
          <Switch>
            <Route
              exact
              path={`${Settings.path}products/:product`}
              component={Product}
            />
          </Switch>
        </main>
        <Footer />
      </div>
    </TotalContext.Provider>
  );
};

现在,我们可以在TotalContext组件中使用total使用者,并调用该方法在全局上下文中设置total方法,如下所示。

代码语言:javascript
复制
./Product.jsx

import { TotalContext } from './Total-Context';

const Product = () => (
<TotalContext.Consumer>
      {({total, setTotal}) => (
        <button
          onClick={() => {setTotal(newTotal)}}
          >
          Update total
        </button>
      )}
</TotalContext.Consumer>
)

因此,在调用click方法之后,Header组件应该具有更新后的total值。

票数 2
EN

Stack Overflow用户

发布于 2019-05-21 02:28:15

您可以使用redux跨多个组件管理状态。

getting started with redux

票数 0
EN

Stack Overflow用户

发布于 2019-05-21 02:48:17

要回答这个问题:没有办法在两个react组件之间传递状态,因为状态是一个组件的私有状态。道具可以在这方面帮助你。道具也不能从子对象传递到父对象,它总是可以从父对象传递到子对象。有一个技巧可以帮助你实现这一点,请遵循下面的文章部分:“如何将道具从子组件传递到父组件?”要弄清楚这一点: URL:https://www.robinwieruch.de/react-pass-props-to-component/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56226280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档