【问题标题】:React - Select Option Changes Based on Other SelectReact - 基于其他选择的选择选项更改
【发布时间】:2021-09-25 10:18:48
【问题描述】:

我正在尝试添加功能,当我选择一种颜色时,它只显示该颜色的尺寸,然后当我选择尺寸时,它只显示该尺寸的可用库存

我创建了一个状态来存储所选颜色的值,但我不知道如何将它与该颜色的大小绑定,然后将大小与库存绑定!

// products.js

const products = [
  {
    _id: '1',
    name: 'Men solid drop shoulder neck regular fit pullover t-shirts',
    category: 'Man',
    subcat: 'Tshirt',
    type: 'Shoulder',
    fabric: '100% Cotton',
    price: 89.99,
    variants: [
        {   
            color:'black',
            sizes:[
                {
                   size:'S',
                   stock:3
                },
                {
                   size:'L',
                   stock:12,
                }
            ]
        },

        {   
            color:'white',
            sizes:[
                {
                   size:'M',
                   stock:8
                },
                {
                   size:'L',
                   stock:2
                },
                {
                   size:'XL',
                   stock:10
                }
            ]
        }
    ],


// Product.js

import  { useState } from 'react';
import { ListGroup, Row, Col, Card,Form, Button } from 'react-bootstrap'
const Product = ({product}) => {

const [colorState, setColorState] = useState('');

    return (
        <Card className="my-3 p-3 rounded">
          <Card.Text as='div'>
              <ListGroup.Item >
                <Row>
                  <Col>
                    <Form.Control as="select" onChange={(e)=> {
                      const selectedColor = e.target.value;
                      setColorState(selectedColor);

                    }} >
                      <option value="" disabled selected hidden>Color</option>
                      {product.variants.map(variant => <option value={variant.color}>{variant.color}</option>)}
                    </Form.Control>
                    {colorState}
                  </Col>
                  <Col>
                    <Form.Control as="select" 
                     >
                      <option value="" disabled selected hidden>Size</option>
                     {product.variants[0].sizes.map(sizes => <option value={sizes.size}>{sizes.size}</option>)} 
                    </Form.Control>

                    Quantity: <input type="number" name="points"  min='1' max={product.variants[0].sizes[0].stock}/>
                  </Col>

                </Row>
              </ListGroup.Item>
            </div>
          </Card.Text>
          <Button variant="primary">Purchase</Button>{' '}
        </Card>


    )
}

export default Product




【问题讨论】:

    标签: javascript reactjs ecmascript-6


    【解决方案1】:

    您可以将产品组件更新为如下所示

    
    const Product = ({product}) => {
    
    const [colorState, setColorState] = useState('');
        return (
          <Card className="my-3 p-3 rounded">
              <Card.Text as='div'>
                  <ListGroup.Item >
                    <Row>
                      <Col>
                        <Form.Control as="select" onChange={(e)=> {
                          const selectedColor = e.target.value;
                          setColorState(selectedColor);
    
                        }} >
                          <option value="" disabled selected hidden>Color</option>
                          {product.variants.map(variant => <option value={variant.color}>{variant.color}</option>)}
                        </Form.Control>
                        {colorState}
                      </Col>
                      <Col>
                        <Form.Control as="select">
                          <option value="" disabled selected hidden>Size</option>
                          {product.variants.map(variant=> {
                            if(variant["color"] === colorState){
                              return variant.sizes.map(sizes => <option value={sizes.size}>{sizes.size}</option>)
                            }
                            return ""
                          })}
                        </Form.Control>
                        Quantity: <input type="number" name="points"  min='1' max={product.variants[0].sizes[0].stock}/>
                      </Col>
    
                    </Row>
                  </ListGroup.Item>
              </Card.Text>
              <Button variant="primary">Purchase</Button>{' '}
            </Card>
          )
    }
    
    export default Product
    

    【讨论】:

      【解决方案2】:

      与 Mohamed 的回答类似,但也添加了最大数量:

        const products = [
          {
            _id: "1",
            name: "Men solid drop shoulder neck regular fit pullover t-shirts",
            category: "Man",
            subcat: "Tshirt",
            type: "Shoulder",
            fabric: "100% Cotton",
            price: 89.99,
            variants: [
              {
                color: "black",
                sizes: [
                  {
                    size: "S",
                    stock: 3
                  },
                  {
                    size: "L",
                    stock: 12
                  }
                ]
              },
      
              {
                color: "white",
                sizes: [
                  {
                    size: "M",
                    stock: 8
                  },
                  {
                    size: "L",
                    stock: 2
                  },
                  {
                    size: "XL",
                    stock: 10
                  }
                ]
              }
            ]
          }
        ];
        //----------------------------------------------------
        const product = products[0];
        const [colorState, setColorState] = useState("");
        const [selectedSize, setSelectedSize] = useState("");
        return (
          <div className="App">
            <Card className="my-3 p-3 rounded">
              <Card.Text as="div">
                <ListGroup.Item>
                  <Row>
                    <Col>
                      <Form.Control
                        as="select"
                        onChange={(e) => {
                          const selectedColor = e.target.value;
                          setColorState(selectedColor);
                        }}
                      >
                        <option value="" disabled selected hidden>
                          Color
                        </option>
                        {product.variants.map((variant) => (
                          <option value={variant.color}>{variant.color}</option>
                        ))}
                      </Form.Control>
                      {colorState}
                    </Col>
                    <Col>
                      <Form.Control
                        as="select"
                        onChange={(e) => {
                          setSelectedSize(e.target.value);
                        }}
                      >
                        <option value="" disabled selected hidden>
                          Size
                        </option>
                        {product.variants.map((variant) => {
                          if (variant["color"] === colorState) {
                            return variant.sizes.map((sizes) => (
                              <option value={sizes.size}>{sizes.size}</option>
                            ));
                          }
                          return "";
                        })}
                      </Form.Control>
                      Quantity:
                      {selectedSize && (
                        <input
                          type="number"
                          name="points"
                          min="1"
                          max={
                            product.variants[0].sizes.filter(
                              (size) => size.size === selectedSize
                            )[0].stock
                          }
                        />
                      )}
                    </Col>
                  </Row>
                </ListGroup.Item>
              </Card.Text>
              <Button variant="primary">Purchase</Button>{" "}
            </Card>
          </div>
        );
      }
      

      【讨论】:

      • 谢谢!您确实将 const product = products[0] 设置为仅索引确切的对象,但在我的情况下,我的数组中有很多对象,我尝试映射 product.variants 然后过滤大小,但我认为我编码错误,你能帮我解决这个问题吗!
      【解决方案3】:

      我将通过将所有输入字段(例如颜色、尺寸和数量)转换为受控组件来以稍微不同的方式执行此操作。因为,它让我可以更好地控制在颜色更改时更新/重置特定数量/大小,以及在单独更改大小时更新/重置数量。

      另外,我将存储产品对象的选定变体,而不是仅存储颜色本身和相同大小的大小写,而不是仅存储尺寸,我将存储选择的尺寸对象,通过它我可以控制数量。

      在所有这些更改之后,这就是我的Product.js 的样子。

      // Product.js
      
      import { useState } from "react";
      import { ListGroup, Row, Col, Card, Form, Button } from "react-bootstrap";
      
      const Product = ({ product }) => {
        const defaultVariantObj = { color: "", sizes: [] };
        const [selectedVariant, setSelectedVariant] = useState(defaultVariantObj);
        const defaultSizeObj = { size: "", stock: 0 };
        const [selectedSize, setSelectedSize] = useState(defaultSizeObj);
        const defaultQuantity = 0;
        const [selectedQuantity, setSelectedQuantity] = useState(defaultQuantity);
      
        return (
          <Card className="my-3 p-3 rounded">
            <Card.Text as="div">
              <ListGroup.Item>
                <Row>
                  <Col>
                    <Form.Control
                      as="select"
                      onChange={(e) => {
                        const {
                          target: { value }
                        } = e;
                        setSelectedVariant(
                          product.variants.find(({ color }) => color === value) || {}
                        );
                        setSelectedSize(defaultSizeObj);
                        setSelectedQuantity(defaultQuantity);
                      }}
                      value={selectedVariant.color}
                    >
                      <option value="" disabled selected hidden>
                        Color
                      </option>
                      {product.variants.map((variant) => (
                        <option value={variant.color}>{variant.color}</option>
                      ))}
                    </Form.Control>
                    {selectedVariant.color}
                  </Col>
                  <Col>
                    <Form.Control
                      as="select"
                      onChange={(e) => {
                        const {
                          target: { value }
                        } = e;
                        setSelectedSize(
                          selectedVariant?.sizes.find(({ size }) => size === value) ||
                            {}
                        );
                        setSelectedQuantity(defaultQuantity);
                      }}
                      value={selectedSize.size}
                    >
                      <option value="" disabled selected hidden>
                        Size
                      </option>
                      {selectedVariant?.sizes?.map((sizeObj) => (
                        <option key={sizeObj.size} value={sizeObj.size}>
                          {sizeObj.size}
                        </option>
                      ))}
                    </Form.Control>
                    Quantity:{" "}
                    <input
                      type="number"
                      name="points"
                      min={!selectedSize?.stock ? 0 : 1}
                      max={selectedSize?.stock || 0}
                      value={selectedQuantity}
                      onChange={(e) => {
                        const {
                          target: { value }
                        } = e;
                        setSelectedQuantity(value);
                      }}
                    />
                  </Col>
                </Row>
              </ListGroup.Item>
            </Card.Text>
            <Button variant="primary">Purchase</Button>{" "}
          </Card>
        );
      };
      
      export default Product;
      
      

      这是沙盒的Link。为了在沙盒中简单起见,我只使用了两个产品,以便处理多个产品(如果有的话)。

      【讨论】:

      • 非常感谢,这个方法很精准!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      • 1970-01-01
      • 2021-05-27
      • 1970-01-01
      相关资源
      最近更新 更多