Как я могу добавить цены на объекты

#javascript #arrays #reactjs #object

Вопрос:

У меня есть множество объектов. Модель, двигатель, коробка передач. У каждого объекта есть свое название и цена.

 const ModelsTypes = [
        {
            name: "pro rs3",
            price: 100000,
        },
        {
            name: "uber rs2",
            price: 50000,
        },
        {
            name: "standard",
            price: 10000,
        },
        {
            name: "wk",
            price: 5000,
        },
    ]

const EngineTypes = [
        {
            name: "5.2l 532bhp",
            price: 10000,
        },
        {
            name: "4.2l 443bhp",
            price: 9000,
        },
        {
            name: "3.6 374bhp",
            price: 5000,
        },
        {
            name: "2.0 166bhp",
            price: 1000,
        },
    ]

const Gearbox = [
        {
            gearbox: "Manual",
            price: 5000,
        },
        {
            gearbox: "Automatic",
            price: 10000,
        },
    ]
 

Пользователь может выбрать любую конфигурацию. Затем все выбранные параметры отображаются в сводке. Как я могу добавить цены на каждое свойство, выбранное пользователем. Нужно ли мне другое состояние использования, чтобы суммировать цену?

Это часть кода, которая возвращает все объекты в массиве.

 {ModelsTypes.map(model =>
     <div>
      <label>{model.name}</label>
      <input onClick={addCarModel} type="radio" name="Model" value={model.name} />
     </div>
)}

{EngineTypes.map(engine =>
     <div>
      <label>{engine.name}</label>
      <input onClick={addCarEngine} type="radio" name="Model" value={engine.name} />
     </div>
)}

{Gearbox.map(gearbox =>
     <div>
      <label>{gearbox.gearbox}</label>
      <input onClick={addCarGearbox} type="radio" name="Model" value={gearbox.gearbox} />
     </div>
)}

 

Функции, используемые компонентами

 const addCarModel = (e) => {
 setCarModel(carModel => e.target.value);
}

const addCarEngine = (e) => {
 setCarEngine(carEngine => e.target.value);
}

const addCarGearbox = (e) => {
 setCarGearbox(carGearbox => e.target.value);
}

 

Краткие сведения

 <div className={styles.summaryinfo}>
 <ul>
  <li>Model: <span>{carModel}</span></li>
  <li>Engine: <span>{carEngine}</span></li>
  <li>Gearbox: <span>{carGearbox}</span></li>
  <li>Price: <span>${totalPrice}</span></li>
 </ul>
</div>
 

Ответ №1:

Если вы сохраняете все фактические объекты, выбранные в состоянии, вы можете легко просто использовать price внутреннюю часть useEffect

 useEffect( () => {
  setTotalPrice( (carModel.price   carEngine.price   carGearbox.price) || 0);
},[carModel,carEngine,carGearbox])

const addCarModel = (e) => {
 setCarModel(carModel => ModelsTypes.find(x => x.name == e.target.value));
}

const addCarEngine = (e) => {
 setCarEngine(carEngine => EngineTypes.find(x => x.name == e.target.value));
}

const addCarGearbox = (e) => {
 setCarGearbox(carGearbox => Gearbox.find(x => x.gearbox == e.target.value));
}
 

Живой пример:

 const ModelsTypes=[{name:"pro rs3",price:1e5},{name:"uber rs2",price:5e4},{name:"standard",price:1e4},{name:"wk",price:5e3}],EngineTypes=[{name:"5.2l 532bhp",price:1e4},{name:"4.2l 443bhp",price:9e3},{name:"3.6 374bhp",price:5e3},{name:"2.0 166bhp",price:1e3}],Gearbox=[{gearbox:"Manual",price:5e3},{gearbox:"Automatic",price:1e4}];
    
    
const App = () => {
    const [carModel,setCarModel] = useState("");
    const [carEngine,setCarEngine] = useState("");
    const [carGearbox,setCarGearbox] = useState("");
    const [totalPrice,setTotalPrice] = useState(0);
    
    useEffect( () => {
      setTotalPrice( (carModel.price   carEngine.price   carGearbox.price) || 0);
    },[carModel,carEngine,carGearbox])

    const addCarModel = (e) => {
     setCarModel(carModel => ModelsTypes.find(x => x.name == e.target.value));
    }

    const addCarEngine = (e) => {
     setCarEngine(carEngine => EngineTypes.find(x => x.name == e.target.value));
    }

    const addCarGearbox = (e) => {
     setCarGearbox(carGearbox => Gearbox.find(x => x.gearbox == e.target.value));
    }

    return (
     <div>
        {ModelsTypes.map(model =>
             <div>
              <label>{model.name}</label>
              <input onClick={addCarModel} type="radio" name="Model" value={model.name} />
             </div>
        )}

        {EngineTypes.map(engine =>
             <div>
              <label>{engine.name}</label>
              <input onClick={addCarEngine} type="radio" name="Engine" value={engine.name} />
             </div>
        )}

        {Gearbox.map(gearbox =>
             <div>
              <label>{gearbox.gearbox}</label>
              <input onClick={addCarGearbox} type="radio" name="Gearbox" value={gearbox.gearbox} />
             </div>
        )}

        <div>
         <ul>
          <li>Model: <span>{carModel.name}</span></li>
          <li>Engine: <span>{carEngine.name}</span></li>
          <li>Gearbox: <span>{carGearbox.gearbox}</span></li>
          <li>Price: <span>${totalPrice}</span></li>
         </ul>
        </div>
      </div>
   )
    
}

ReactDOM.render(<App />, document.getElementById("root")) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js" integrity="sha256-32Gmw5rBDXyMjg/73FgpukoTZdMrxuYW7tj8adbN8z4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js" integrity="sha256-bjQ42ac3EN0GqK40pC9gGi/YixvKyZ24qMP/9HiGW7w=" crossorigin="anonymous"></script>
<script>
  var {
    useReducer,
    useEffect,
    useState,
    useRef,
    useCallback
  } = React
</script>
<div id="root"></div> 

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

1. Я начинаю изучать этот код, чтобы понять его, но была еще одна проблема. После копирования его в мое приложение и выбора значения я получаю следующую ошибку. Ошибка: Объекты недопустимы как дочерние (найдено: объект с ключами {имя, цена}). Если вы хотели отобразить коллекцию дочерних элементов, вместо этого используйте массив.

2. @Navro вы заметили, что мне пришлось изменить визуализацию раздела резюме? от, например <li>Model: <span>{carModel}</span></li> , до <li>Model: <span>{carModel.name}</span></li>

3. О, мне жаль, что я не заметил этого в первый раз. Большое вам спасибо за помощь

4. @Navro — Рад, что здесь Jamiec смог предоставить вам рабочее решение. Пожалуйста, не забудьте принять правильные рабочие ответы, щелкнув флажок под ними-это обеспечивает репутацию ответчику, а также указывает новым посетителям этого поста, что этот ответ сработал для вас. Удачи и счастливого кодирования!

Ответ №2:

Вы можете использовать array.reduce выбранные детали для получения общей цены:

 [carModel, carEngine, carGearbox].reduce((total, item)=>total   item.price,0)
 

В качестве альтернативы вы можете использовать другую переменную состояния и суммировать ее в любое время, когда элемент выбирается внутри useEffect :

 const [total, setTotal] = setState(0);
useEffect(()=>{
  setTotal(carModel.price   carEngine.price   carGearbox.price)
},[carModel, carEngine, carGearbox])
 

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

1. Я не знаю почему, но при попытке добавить второе решение общее количество содержит NaN вместо суммы его частей.