javascript - 如何从类组件更新功能组件的状态,以便在反应中显示地图中的项目
问题描述
我在 Gatsby JS 中有一个 StoreDetails 功能组件,它使用 UseState 挂钩从 graphQL 中的地图有条件地呈现产品,这些产品与状态值匹配。我有一个类组件下拉菜单,当前手动填充了 sku'id,这些 sku'id 将匹配要在状态和映射条件语句中显示的条件。我希望下拉菜单更改功能组件的状态,以便在下拉菜单中选择正确的产品时显示。我正在玩弄将状态函数作为道具传递,但我遇到了重新渲染问题,非常卡在这里。
关键在这一{value.skuId === sku.skuId ?
行当它仍在地图内时,如何根据选项下拉菜单更改它
提前感谢
到目前为止,这是我的代码
import React, {useState} from 'react';
import Layout from "../components/layout"
import styled from 'styled-components';
import {loadStripe} from '@stripe/stripe-js';
// import Alert from '../components/Alert';
import { navigate } from "gatsby";
import Img from "gatsby-image"
const StoreHero = styled.section`
width:1280px;
margin:0 auto;
`
class Alert extends React.Component{
constructor(props){
super(props);
//console.log(props);
this.state = {test:"test",hello:"hello1",hash:props.hash}
}
render(){
const { test, hello, hash } = this.state
//console.log(hash);
return(
<div>{hash}</div>
)
}
}
class ShowItem extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'coconut'};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
console.log(event.target.value);
// Right here is where I want to change the state of the value variable below so
// that the correct product is shown based on the dropdown sku selection
}
render() {
return (
<select value={this.state.value} onChange={this.handleChange}>
<option value="sku_HAD1kUsbV3GpgW">sku_HAD1kUsbV3GpgW</option>
<option value="sku_HACMgLjJBZFR7A">sku_HACMgLjJBZFR7A</option>
</select>
);
}
}
class Product extends React.Component{
constructor(props) {
super(props);
this.state = {
stripe: null
};
this.loadStripeLib = this.loadStripeLib.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
this.loadStripeLib()
}
async loadStripeLib() {
try {
const stripe = await loadStripe('pk_test_random');
this.setState({ stripe });
} catch {
// do nothing
}
}
handleSubmit(sku, productId){
return event => {
event.preventDefault();
this.state.stripe.redirectToCheckout({
items: [{sku, quantity: 1}],
successUrl: `http://localhost:8000/store/${productId}#success`,
cancelUrl: `http://localhost:8000/store/${productId}#cancelled`,
}).then(function (result) {
// Display result.error.message to your customer
console.error(result);
});
}
}
render(){
const { id, currency, price, name, productId } = this.props
const priceFloat = (price / 100).toFixed(2)
const formattedPrice = Intl.NumberFormat('en-US', {
style: 'currency',
currency,
}).format(priceFloat)
return(
<form onSubmit={this.handleSubmit(id, productId)}>
<h2>
{name} ({formattedPrice})
</h2>
<button type="submit">Buy Now</button>
</form>
)
}
}
const StoreDetails = ({data, location}) =>{
const [value, setValue] = useState({
skuId: "sku_HAD1kUsbV3GpgW"
});
//console.log(value);
return(
<Layout>
<StoreHero>
<Alert test="test" hello="hello" hash={location.hash}/>
{/* <ShowItem props={data}/> */}
{data.allDatoCmsStore.edges.map(({ node: sku }) => (
<>
{value.skuId === sku.skuId ?
<>
<ShowItem setValue={setValue}/>
<Product
key={sku.id}
id={sku.skuId}
productId={sku.productId}
currency="cad"
price={sku.price}
name={sku.title}
/>
<Img fixed={sku.image.fixed}/>
</>
:
null
}
</>
))}
</StoreHero>
</Layout>
)
}
export default StoreDetails
export const query = graphql`
query StoreDeatailsQuery($slug: String!) {
allDatoCmsStore(filter: {productId: {eq: $slug}}) {
edges {
node {
price
productId
skuId
title
id
image{
fixed{
...GatsbyDatoCmsFixed
}
}
}
}
}
allStripeSku {
edges {
node {
id
currency
price
attributes {
name
}
image
localFiles {
childImageSharp {
fixed(width: 125) {
...GatsbyImageSharpFixed
}
}
}
}
}
}
}
`
解决方案
看起来我把它复杂化了,我还有更多工作要做,但是把它改成这个对我来说是固定的
const StoreDetails = ({data, location}) =>{
const [value, setValue] = useState({
skuId: "sku_HAD1kUsbV3GpgW"
});
const run = (event) =>{
console.log(event);
setValue({skuId:event})
}
return(
<Layout>
<StoreHero>
<Alert test="test" hello="hello" hash={location.hash}/>
{/* <ShowItem props={data}/> */}
{data.allDatoCmsStore.edges.map(({ node: sku }) => (
<>
{value.skuId === sku.skuId ?
<>
<select onChange={(event) => run(event.target.value)}>
<option value="sku_HAD1kUsbV3GpgW">sku_HAD1kUsbV3GpgW</option>
<option value="sku_HACMgLjJBZFR7A">sku_HACMgLjJBZFR7A</option>
</select>
{/* <ShowItem setValue={setValue}/> */}
<Product
key={sku.id}
id={sku.skuId}
productId={sku.productId}
currency="cad"
price={sku.price}
name={sku.title}
/>
<Img fixed={sku.image.fixed}/>
</>
:
null
}
</>
))}
</StoreHero>
</Layout>
)
}
推荐阅读
- python - 将信息从 python 传递到 c prog
- tensorflow - 我想构建 2 个解码器副本,其中包含具有不同 droupout 的相同 FC 层,但我希望它们共享权重。如何才能做到这一点?
- vba - 带有 SAP 的语句结束 VBA
- c# - 使用 C# UWP 应用程序控制树莓派的音量
- javascript - 如何用烧瓶和 jquery 解决这个问题?HTTP400: BAD REQUEST - 由于语法无效,服务器无法处理请求
- c# - error CS0150: A constant value is expected //switch 语句中的错误
- sql - 如何根据最大列值找到对应的行数据?
- python - 如何在 Python 中将列表 [a,b] 转换为 [[a],[b]]?单行功能,例如地图
- javascript - html2canvas 导致 IE11 挂起并进入“无响应”状态
- hibernate - 给定其类或类型,是否有任何方法可以创建持久实体示例?