#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 вместо суммы его частей.