我是React JS的新手。我正在尝试将状态从另一个组件更新到另一个组件。 有人可以帮我解决吗?
当我点击 product.jsx 上的添加到购物车按钮时,我希望更新 header.jsx 上的状态总计 >
非常感谢
这是我的代码
index.jsx
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
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
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;
答案 0 :(得分:2)
您可以执行以下操作来实现此目的。但是React JS建议的更干净的解决方案是使用React Context API。
Am共享了React JS文档中的链接,这些链接完全具有您要解决的相同情况。
https://reactjs.org/docs/context.html#updating-context-from-a-nested-component
另外,由于您使用的是React纯组件函数,因此我们可以使用React钩子,因此您可以在
中查看https://reactjs.org/docs/hooks-reference.html#usestate
所以在您的代码中应该是这样
./Total-Context.js
export const TotalContext = React.createContext({
total: 0,
setTotal: () => {
},
});
./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>
);
};
现在我们可以在Product组件中使用TotalContext使用者,并调用该方法在全局上下文中设置total方法,就像这样。
./Product.jsx
import { TotalContext } from './Total-Context';
const Product = () => (
<TotalContext.Consumer>
{({total, setTotal}) => (
<button
onClick={() => {setTotal(newTotal)}}
>
Update total
</button>
)}
</TotalContext.Consumer>
)
因此,在调用click方法之后,Header组件应该具有总计的更新值。
答案 1 :(得分:0)
您可以使用redux来管理多个组件之间的状态。
答案 2 :(得分:0)
要回答此问题: 由于状态是组件专有的,因此无法借助它在两个React组件之间传递状态。 道具可以在这方面帮助您。道具也不能从孩子传递给父母,它总是可以从父母传递给孩子。 您可以借助帮助实现这一点,请遵循以下文章部分:“如何将道具从子组件传递到父组件?”要对此有个清楚的主意: 网址:https://www.robinwieruch.de/react-pass-props-to-component/