Получить идентификатор на основе динамических выбранных значений в React

#javascript #arrays #reactjs #ecmascript-6 #react-hooks

Вопрос:

У меня есть несколько productOptionTypes с динамическими значениями. Моя проблема в том, как мне сопоставить его с его variants . Я хочу получить на variant id его основе.

Пожалуйста, проверьте код и поле здесь, НАЖМИТЕ ЗДЕСЬ

 {productOptionTypes.map((item, index) => (
  <>
    <span className="title">{item.optionName}</span>
    <Select
      placeholder={`${item?.optionValues?.length} ${item.optionName}s`}
      options={item.optionValues.map((option) => {
        return { label: option, value: option };
      })}
      isSearchable={false}
      onChange={(value) => handleSelectVariant(value, index)}
    />
  </>
))}
 

Комментарии:

1. Вы пытаетесь использовать значения типа опции продукта для поиска/фильтрации данных вариантов? Что вы хотите хранить в variantType штате? Как вы хотите, чтобы данные соотносились?

2. @DrewReese. Я просто хочу сохранить данные, handleSelectVariant потому что моя цель-просто отфильтровать их, чтобы получить на variant id их основе.

3. Я копаюсь в вашей песочнице, но что непонятно, так это UX. Похоже , вам нужен один вариант id , но неясно, как связаны эти две коллекции, кроме как с помощью типов опций. С чем вы пытаетесь сравниться? Вам нужен абсолютный единичный результат, или вы ищете множество вариантов id , которые соответствуют? Вы используете один тип/значение параметра или несколько?

4. @DrewReese. Я хочу вывести консоль. журнал a single variant id . Это связано с тем, что при выборе из выпадающего списка вы сравниваете его с массивом вариантов

5. Вы должны объяснить, как вы хотите, чтобы массив выбранных параметров и вариантов сравнивался.

Ответ №1:

Лучшее, что я мог придумать, это:

  1. Обновите сопоставление параметров, чтобы вернуть имя параметра, которое будет использоваться в качестве внешнего ключа в объектах variants массива, т. е. «Цвет», «Размер» и т. Д.
     options={item.optionValues.map((option) => {
      return {
        label: option,
        value: option,
        name: item.optionName
      };
    })}
     
  2. Обновите variantType состояние, чтобы оно было объектом, и обновите handleSelectVariant обработчик для хранения типов вариантов по внешнему ключу «имя» и выбранному «значению».
     const [variantType, setSelectedVariant] = useState({});
    
    const handleSelectVariant = (value, index) => {
      setSelectedVariant((state) => ({
        ...state,
        [value.name]: value.value
      }));
    };
     
  3. Используйте filter every функцию и, чтобы свести типы и значения параметров к отфильтрованному результату вариантов, которые можно легко сопоставить со id свойствами.
     const matches = variants
      .filter((variant) => {
        return [
          ["option1Value", "option1Type"],
          ["option2Value", "option2Type"],
          ["option3Value", "option3Type"],
          ["option4Value", "option4Type"],
          ["option5Value", "option5Type"],
          ["option6Value", "option6Type"],
          ["option7Value", "option7Type"],
          ["option8Value", "option8Type"],
          ["option9Value", "option9Type"],
          ["option10Value", "option10Type"]
        ].every(([key, valueKey]) =>
          variantType[variant[valueKey]]
            ? variant[key] === variantType[variant[valueKey]]
            : true
        );
      })
      .map(({ id }) => id);
     

ДЕМОНСТРАЦИЯ

Редактировать get-id-на основе-динамических-выбранных-значений-в-реакции

введите описание изображения здесь

Комментарии:

1. Спасибо. Кстати, OptionValue и optionType являются динамическими. это означает, что если их до 10, то они имеют option10Value и option10Type

2. Я вижу, вы только что добавили статику. Кстати, иногда здесь говорится, что свойство «Не может быть готово» имеет цвет «null». Здесь variantChosen[variant[valueKey]]

3. @Джозеф Интересно, какие варианты вы выбрали, чтобы вызвать эту ошибку?

4. Я думаю, что первый. но иногда это случается, иногда нет. Может быть, вы можете добавить безопасного оператора…?

5. @Джозеф, это ошибка в моем коде и коробке? После выбора цветов в течение минуты подряд я не вижу никакой ошибки. Какие шаги (шаги воспроизведения) вы делаете, чтобы вызвать ошибку?

Ответ №2:

Когда я правильно понимаю, вы хотите сохранить каждое выбранное значение, затем сравнить результат с вашими вариантами и выбрать идентификатор элемента, соответствующий всем полям выбора на его основе?

index.js

 import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import Select from "react-select";
import "./styles.css";
import { productOptionTypes } from "./productOptionTypes";
import { variants } from "./variants";

function App() {
  const [variantType, setSelectedVariant] = useState({});
  const [result, setResult] = useState(null);

  const mapIndexKey = {
    0: "option1Value",
    1: "option2Value",
    2: "option3Value",
    3: "option4Value"
  };

  useEffect(() => {
    setResult(
      variants.filter(
        (el) =>
          el.option1Value == variantType.option1Value amp;amp;
          el.option2Value == variantType.option2Value amp;amp;
          el.option3Value == variantType.option3Value amp;amp;
          el.option4Value == variantType.option4Value
      )
    );
  }, [variantType]);

  useEffect(() => {
    console.log(result);
  }, [result]);

  const handleSelectVariant = (value, index) => {
    setSelectedVariant({ ...variantType, [mapIndexKey[index]]: value.value });
    console.log(variantType, value, index);
  };

  return (
    <div className="App">
      <form>
        {productOptionTypes.map((item, index) => (
          <>
            <span className="title">{item.optionName}</span>
            <Select
              placeholder={`${item?.optionValues?.length} ${item.optionName}s`}
              options={item.optionValues.map((option) => {
                return { label: option, value: option };
              })}
              isSearchable={false}
              onChange={(value) => handleSelectVariant(value, index)}
            />
          </>
        ))}
      </form>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
 

variants.js

 export const variants = [
  {
    id: "60451fd290aeb720d96d8459",
    name: "Women's Bellarina Half Toe Grip Yoga Pilates Barre Socks",
    wholesalePrice: "8.0",
    sku: "s01524blk",
    option1Type: "Color",
    option1Value: "Black",
    option2Type: "Size",
    option2Value: "XS",
    option3Type: "Toe Type",
    option3Value: "Half Toe",
    option4Value: "Bellarina",
    retailPrice: "16.0",
    __typename: "Variant"
  },
  {
    id: "60451fd790aeb720d96d8463",
    name: "Women's Bellarina Half Toe Grip Yoga Pilates Barre Socks",
    wholesalePrice: "8.0",
    sku: "s01525blk",
    option1Type: "Color",
    option1Value: "Black",
    option2Type: "Size",
    option2Value: "S",
    option3Type: "Toe Type",
    option3Value: "Half Toe",
    retailPrice: "16.0",
    __typename: "Variant"
  }
}
 

В основном я сохраняю все выбранные значения на карте, и каждый раз, когда значение изменяется, просто сравниваю его со всеми вариантами, если вариант равен, я выбираю его.
Для одного варианта я добавил четвертый ключ «Белларина».

Я надеюсь, что это решение решит вашу проблему.

Если вы хотите проверить решение, просто выберите первое значение каждого поля выбора и посмотрите на консоль.

Комментарии:

1. можете ли вы раскошелиться на мой код и коробку, чтобы я мог легко проверить. Спасибо. Кстати, опции являются динамическими

2. Нужна ли мне учетная запись codesandbox? Я нажал на вилку, но у меня нет учетной записи…. тем не менее, вы видите вилку?

3. Да, это создаст новую ссылку, когда вы разветвляетесь. Вы можете вставить новую ссылку здесь