Отображение данных Javascript / React
Мое решение реализовать статус (строку) из объединения двух других. Мне нужно объявить функцию, которая принимает два параметра (две строки) и должна возвращать еще один на основе комбинации этих двух строк. Например:
carStatus(status, secondaryStatus) => string
где secondaryStatus может иметь несколько параметров. Я использую оператор if / else if, который возвращает третий статус, который мне нужен. Например, когда статус - «ОТКРЫТО», а вторичный статус - «payment1», «payment2» или «payment3», функция должна возвращать новую строку (статус), например «CONFIRMED». Итак, мое решение на данный момент будет примерно таким:
carStatus = (status, secondaryStatus) => {
if(status === 'OPEN' && (secondaryStatus === 'payment1' || 'payment2' || 'payment3')){
return 'CONFIRMED';
} else if(status === 'CANCELLED' && (secondaryStatus === 'payment4' || 'payment5' || 'payment6')){
return 'REMOVED';
} else if(status === 'REVIEW' && (secondaryStatus === 'payment2' || 'payment5' || 'payment5')){
return 'CHECKED';
}
}
<div>carStatus('OPEN', 'payment1')</div>
В div должно быть указано «ПОДТВЕРЖДЕНО».
В моей реализации я должен написать еще 5 операторов else if ... так что, возможно, есть более чистый способ реализовать это.
Любая помощь будет оценена по достоинству.
Ответы
Ошибка условия В вашей текущей реализации есть ошибка. У ваших строк, подобных этим, есть проблема:
(secondaryStatus === 'payment1' || 'payment2' || 'payment3')
В JavaScript есть только унарные операторы, бинарные операторы и один тернарный оператор. Все использованные выше операторы являются бинарными операторами; два выражения будут преобразованы в одно выражение, пока не останется одно. Поскольку ===имеет более высокий приоритет оператора, чем ||, ваш код эквивалентен:
(secondaryStatus === 'payment1' || 'payment2' || 'payment3')
(trueOrFalse || 'payment2' || 'payment3')
payment2И payment3не сравниваются с secondaryStatus, и если secondaryStatusэто не payment1, все выражение будет вычисляться 'payment2', значение truthy (потому что ||будет оценивать на второе значение , если первый falsey):
// || operates left-to-right:
(trueOrFalse || 'payment2' || 'payment3')
((false || 'payment2') || 'payment3')
(('payment2') || 'payment3')
// payment2 is truthy, so the `||` evaluates to it:
('payment2')
Чтобы исправить логику, используйте вместо этого массив и проверьте статус каждого элемента в массиве.
Опечатка? У вас есть (secondaryStatus === 'payment2' || 'payment5' || 'payment5'), причем payment5дважды. Вы имели в виду что-то еще, например payment9?
Имена carStatus не содержат статуса автомобиля, как это могло бы звучать; это функция, которая при вызове возвращает статус автомобиля. Он также принимает параметр с похожим названием status. Назовите их как-нибудь иначе, если это вообще возможно: возможно, getCarStatusи что-то более конкретное, что statusпредставляет параметр. Может позвонить secondaryStatus: paymentType.
DRY Вы также хотите сделать код более СУХИМ, что хорошо согласуется с идеей использования массивов. Вы можете использовать объект, ключи которого - это требуемый статус, а значения - возможные secondaryStatusзначения, а также возвращаемое значение, если secondaryStatusон найден.
Кроме того, поскольку все строки оплаты заканчиваются числом, и это число - единственное, что изменяется, используйте этот номер для настройки объекта конфигурации вместо полных paymentстрок:
const statusOptions = {
OPEN: { paymentNumbers: [1, 2, 3], status: 'CONFIRMED' },
CANCELLED: { paymentNumbers: [4, 5, 6], status: 'REMOVED' },
REVIEW: { paymentNumbers: [2, 5], status: 'CHECKED' },
};
// ...
getCarStatus = (status, paymentType) => {
const possibleOption = statusOptions[status];
if (possibleOption) {
const paymentNumber = Number(paymentType.match(/\d+$/)[0]);
if (possibleOption.paymentNumbers.includes(paymentNumber)) {
return possibleOption.status;
}
}
}
Живой фрагмент:
const statusOptions = {
OPEN: { paymentNumbers: [1, 2, 3], status: 'CONFIRMED' },
CANCELLED: { paymentNumbers: [4, 5, 6], status: 'REMOVED' },
REVIEW: { paymentNumbers: [2, 5], status: 'CHECKED' },
};
// ...
getCarStatus = (status, paymentType) => {
const possibleOption = statusOptions[status];
if (possibleOption) {
const paymentNumber = Number(paymentType.match(/\d+$/)[0]);
if (possibleOption.paymentNumbers.includes(paymentNumber)) {
return possibleOption.status;
}
}
};
console.log(
getCarStatus('OPEN', 'payment3'),
getCarStatus('REVIEW', 'payment2')
);
Тип компонента Похоже, вы используете компонент класса. React рекомендует попробовать использовать функциональные компоненты в новом коде; они говорят, что с ними немного легче работать и понимать, чем компоненты на основе классов в большинстве случаев, и я согласен. Вместо этого попробуйте использовать функциональные компоненты, если вы еще этого не сделали, они могут вам понравиться.