React 中来自 API 的状态
State from API in React
我正在执行一个可以修改产品价格的项目(从假货 API 中检索),然后单击一个按钮,我通过计算 20% 的增值税来更新。我遇到一个问题,我想要一个价格状态,在这个状态下,它是我输入的值,即 {listProduct.price},所以我的 API 的价格最初显示在输入(即第一篇文章 105.95 美元,...)但它不起作用。
您将首先找到显示产品页面的 productsDetails 部分的代码,以及从 API
检索数据的产品代码
如果您有任何我感兴趣的解决方案,请提前致谢。 (抱歉,我是 React 的新手,我仍然在为所有这些概念而苦苦挣扎)
产品详情
import React, { Component } from 'react'
import '../css/ProductsDetails.css'
import {AiOutlineArrowLeft} from "react-icons/ai";
import {Link} from 'react-router-dom'
export default class ProductsDetails extends Component {
constructor(props) {
super(props);
this.state = {id: this.props.match.params.id, price: };
}
updatePrice = (e) => {
console.log(e);
this.setState({
price: e.target.value
})
}
render() {
const {location: {state: {listProduct}}} = this.props;
return (
<div className="products__details">
<Link to="/"><AiOutlineArrowLeft className="nav__arrow" /></Link>
<h1 className="details__title">{listProduct.title}</h1>
<div className="details__align--desk">
<div className="details__img">
<img className="product__img" src={listProduct.image} alt="Affichage du produit"/>
</div>
<div className="products__align--desk">
<h2 className="product__title">Description</h2>
<p className="product__description">{listProduct.description}</p>
<h2 className="product__title">Price</h2>
<form className="form__price">
<input className="input__price" type="text" value={listProduct.price} onChange={this.updatePrice} />
<p>Price (including VAT): {Math.round((listProduct.price + listProduct.price * 0.2)*100) /100} €</p>
<br/>
<input className="btn__update" type="submit" value="Update product" />
</form>
</div>
<div className="category__align--desk">
<h2 className="product__title">Category</h2>
<p className="product__category">{listProduct.category}</p>
</div>
</div>
</div>
)
}
}
产品
import React, { Component } from 'react';
import '../css/Products.css';
import axios from 'axios';
import './ProductsDetails'
import {Link} from 'react-router-dom'
export default class Products extends Component {
constructor(props) {
super(props);
this.state = {productsData: []};
}
componentDidMount = () => {
axios.get('https://fakestoreapi.com/products?limit=7')
.then(res => {
console.log(res.data)
this.setState ({
productsData: res.data
})
})
}
render() {
const listsProducts = this.state.productsData.map(listProduct => {
return <tbody className="products__body">
<tr>
<td> <Link to={{pathname: "/products-details/" + listProduct.id,state: {listProduct}}}>{listProduct.title}</Link></td>
<td className="products__category">{listProduct.category}</td>
<td>{listProduct.price}</td>
<td>{Math.round((listProduct.price + listProduct.price * 0.2)*100) /100}</td>
</tr>
</tbody>
})
return (
<main className="products">
<h1 className="products__title">Products management</h1>
<table cellSpacing="0">
<thead className="products__head">
<tr>
<th className="table--title">Product name</th>
<th className="table--title">Category</th>
<th className="table--title">Price</th>
<th className="table--title">Price (including VAT)</th>
</tr>
</thead>
{listsProducts}
</table>
</main>
)
}
}
由于您想在一个组件中显示一些数据并从另一个组件更新 that 数据,那么这里的解决方案是 Lift State Up。将产品状态和数据获取移动到 ProductsDetails
和 Products
组件的共同祖先。
建议:
在父组件中声明productsData
、数据获取和updatePrice
处理程序。
function App() {
const [productsData, setProductsData] = useState([]);
useEffect(() => {
axios.get("https://fakestoreapi.com/products?limit=7").then((res) => {
console.log(res.data);
setProductsData(res.data);
});
}, []);
const updatePrice = (id, price) => {
setProductsData((productsData) =>
productsData.map((product) =>
product.id === Number(id)
? {
...product,
price: Number(price)
}
: product
)
);
};
return (
<div className="App">
<Router>
<Switch>
<Route
path="/products-details/:id"
render={(props) => (
<ProductsDetails
products={productsData}
updatePrice={updatePrice}
{...props}
/>
)}
/>
<Route path="/">
<Products products={productsData} />
</Route>
</Switch>
</Router>
</div>
);
}
更新 Products
以使用来自父级的 products
道具。
class Products extends Component {
render() {
const listsProducts = this.props.products.map((listProduct) => {
return (
<tbody className="products__body" key={listProduct.id}>
<tr>
<td>
{" "}
<Link
to={{
pathname: "/products-details/" + listProduct.id
}}
>
{listProduct.title}
</Link>
</td>
<td className="products__category">{listProduct.category}</td>
<td>{Number(listProduct.price).toFixed(2)}</td>
<td>
{Number(listProduct.price * 1.2).toFixed(2)} €
</td>
</tr>
</tbody>
);
});
return (
<main className="products">
<h1 className="products__title">Products management</h1>
<table cellSpacing="0">
<thead className="products__head">
<tr>
<th className="table--title">Product name</th>
<th className="table--title">Category</th>
<th className="table--title">Price</th>
<th className="table--title">Price (including VAT)</th>
</tr>
</thead>
{listsProducts}
</table>
</main>
);
}
}
更新 ProductsDetails
以使用 products
和 updatePrice
回调道具。为表单创建一个 submitHandler
以更新价格。对于输入,你会想要使用 defaultValue
道具,因为你想提供一个初始值,但 而不是 立即更改原始值数据。
class ProductsDetails extends Component {
constructor(props) {
super(props);
this.state = { id: this.props.match.params.id, price: 0 };
}
updatePrice = (e) => {
console.log(e);
this.setState({
price: e.target.value
});
};
submitHandler = (e) => {
e.preventDefault();
const {
match: {
params: { id }
}
} = this.props;
this.props.updatePrice(id, this.state.price);
};
render() {
const {
match: {
params: { id }
},
products
} = this.props;
const listProduct = products.find((product) => product.id === Number(id));
return (
<div className="products__details">
<Link to="/">
<AiOutlineArrowLeft className="nav__arrow" />
</Link>
<h1 className="details__title">{listProduct.title}</h1>
<div className="details__align--desk">
<div className="details__img">
<img
className="product__img"
src={listProduct.image}
alt="Affichage du produit"
/>
</div>
<div className="products__align--desk">
<h2 className="product__title">Description</h2>
<p className="product__description">{listProduct.description}</p>
<h2 className="product__title">Price</h2>
<form className="form__price" onSubmit={this.submitHandler}>
<input
className="input__price"
type="text"
defaultValue={Number(listProduct.price).toFixed(2)}
onChange={this.updatePrice}
/>
<p>
Price (including VAT):{" "}
{Number(listProduct.price * 1.2).toFixed(2)} €
</p>
<br />
<input
className="btn__update"
type="submit"
value="Update product"
/>
</form>
</div>
<div className="category__align--desk">
<h2 className="product__title">Category</h2>
<p className="product__category">{listProduct.category}</p>
</div>
</div>
</div>
);
}
}
我正在执行一个可以修改产品价格的项目(从假货 API 中检索),然后单击一个按钮,我通过计算 20% 的增值税来更新。我遇到一个问题,我想要一个价格状态,在这个状态下,它是我输入的值,即 {listProduct.price},所以我的 API 的价格最初显示在输入(即第一篇文章 105.95 美元,...)但它不起作用。
您将首先找到显示产品页面的 productsDetails 部分的代码,以及从 API
检索数据的产品代码如果您有任何我感兴趣的解决方案,请提前致谢。 (抱歉,我是 React 的新手,我仍然在为所有这些概念而苦苦挣扎)
产品详情
import React, { Component } from 'react'
import '../css/ProductsDetails.css'
import {AiOutlineArrowLeft} from "react-icons/ai";
import {Link} from 'react-router-dom'
export default class ProductsDetails extends Component {
constructor(props) {
super(props);
this.state = {id: this.props.match.params.id, price: };
}
updatePrice = (e) => {
console.log(e);
this.setState({
price: e.target.value
})
}
render() {
const {location: {state: {listProduct}}} = this.props;
return (
<div className="products__details">
<Link to="/"><AiOutlineArrowLeft className="nav__arrow" /></Link>
<h1 className="details__title">{listProduct.title}</h1>
<div className="details__align--desk">
<div className="details__img">
<img className="product__img" src={listProduct.image} alt="Affichage du produit"/>
</div>
<div className="products__align--desk">
<h2 className="product__title">Description</h2>
<p className="product__description">{listProduct.description}</p>
<h2 className="product__title">Price</h2>
<form className="form__price">
<input className="input__price" type="text" value={listProduct.price} onChange={this.updatePrice} />
<p>Price (including VAT): {Math.round((listProduct.price + listProduct.price * 0.2)*100) /100} €</p>
<br/>
<input className="btn__update" type="submit" value="Update product" />
</form>
</div>
<div className="category__align--desk">
<h2 className="product__title">Category</h2>
<p className="product__category">{listProduct.category}</p>
</div>
</div>
</div>
)
}
}
产品
import React, { Component } from 'react';
import '../css/Products.css';
import axios from 'axios';
import './ProductsDetails'
import {Link} from 'react-router-dom'
export default class Products extends Component {
constructor(props) {
super(props);
this.state = {productsData: []};
}
componentDidMount = () => {
axios.get('https://fakestoreapi.com/products?limit=7')
.then(res => {
console.log(res.data)
this.setState ({
productsData: res.data
})
})
}
render() {
const listsProducts = this.state.productsData.map(listProduct => {
return <tbody className="products__body">
<tr>
<td> <Link to={{pathname: "/products-details/" + listProduct.id,state: {listProduct}}}>{listProduct.title}</Link></td>
<td className="products__category">{listProduct.category}</td>
<td>{listProduct.price}</td>
<td>{Math.round((listProduct.price + listProduct.price * 0.2)*100) /100}</td>
</tr>
</tbody>
})
return (
<main className="products">
<h1 className="products__title">Products management</h1>
<table cellSpacing="0">
<thead className="products__head">
<tr>
<th className="table--title">Product name</th>
<th className="table--title">Category</th>
<th className="table--title">Price</th>
<th className="table--title">Price (including VAT)</th>
</tr>
</thead>
{listsProducts}
</table>
</main>
)
}
}
由于您想在一个组件中显示一些数据并从另一个组件更新 that 数据,那么这里的解决方案是 Lift State Up。将产品状态和数据获取移动到 ProductsDetails
和 Products
组件的共同祖先。
建议:
在父组件中声明
productsData
、数据获取和updatePrice
处理程序。function App() { const [productsData, setProductsData] = useState([]); useEffect(() => { axios.get("https://fakestoreapi.com/products?limit=7").then((res) => { console.log(res.data); setProductsData(res.data); }); }, []); const updatePrice = (id, price) => { setProductsData((productsData) => productsData.map((product) => product.id === Number(id) ? { ...product, price: Number(price) } : product ) ); }; return ( <div className="App"> <Router> <Switch> <Route path="/products-details/:id" render={(props) => ( <ProductsDetails products={productsData} updatePrice={updatePrice} {...props} /> )} /> <Route path="/"> <Products products={productsData} /> </Route> </Switch> </Router> </div> ); }
更新
Products
以使用来自父级的products
道具。class Products extends Component { render() { const listsProducts = this.props.products.map((listProduct) => { return ( <tbody className="products__body" key={listProduct.id}> <tr> <td> {" "} <Link to={{ pathname: "/products-details/" + listProduct.id }} > {listProduct.title} </Link> </td> <td className="products__category">{listProduct.category}</td> <td>{Number(listProduct.price).toFixed(2)}</td> <td> {Number(listProduct.price * 1.2).toFixed(2)} € </td> </tr> </tbody> ); }); return ( <main className="products"> <h1 className="products__title">Products management</h1> <table cellSpacing="0"> <thead className="products__head"> <tr> <th className="table--title">Product name</th> <th className="table--title">Category</th> <th className="table--title">Price</th> <th className="table--title">Price (including VAT)</th> </tr> </thead> {listsProducts} </table> </main> ); } }
更新
ProductsDetails
以使用products
和updatePrice
回调道具。为表单创建一个submitHandler
以更新价格。对于输入,你会想要使用defaultValue
道具,因为你想提供一个初始值,但 而不是 立即更改原始值数据。class ProductsDetails extends Component { constructor(props) { super(props); this.state = { id: this.props.match.params.id, price: 0 }; } updatePrice = (e) => { console.log(e); this.setState({ price: e.target.value }); }; submitHandler = (e) => { e.preventDefault(); const { match: { params: { id } } } = this.props; this.props.updatePrice(id, this.state.price); }; render() { const { match: { params: { id } }, products } = this.props; const listProduct = products.find((product) => product.id === Number(id)); return ( <div className="products__details"> <Link to="/"> <AiOutlineArrowLeft className="nav__arrow" /> </Link> <h1 className="details__title">{listProduct.title}</h1> <div className="details__align--desk"> <div className="details__img"> <img className="product__img" src={listProduct.image} alt="Affichage du produit" /> </div> <div className="products__align--desk"> <h2 className="product__title">Description</h2> <p className="product__description">{listProduct.description}</p> <h2 className="product__title">Price</h2> <form className="form__price" onSubmit={this.submitHandler}> <input className="input__price" type="text" defaultValue={Number(listProduct.price).toFixed(2)} onChange={this.updatePrice} /> <p> Price (including VAT):{" "} {Number(listProduct.price * 1.2).toFixed(2)} € </p> <br /> <input className="btn__update" type="submit" value="Update product" /> </form> </div> <div className="category__align--desk"> <h2 className="product__title">Category</h2> <p className="product__category">{listProduct.category}</p> </div> </div> </div> ); } }