Код-ревью Middle Компоненты и стили обновлено
Код-ревью: карточка товара
Вопрос
Компонент карточки товара. Найдите проблемы вёрстки, платформенных различий и производительности.
export const ProductCard = memo(({ product, onBuy }: Props) => {
const { width } = Dimensions.get('window');
return (
<View style={{ width: width / 2, padding: 8, color: '#333', shadowOpacity: 0.2 }}>
<Image source={{ uri: product.photoUrl }} />
{product.discount && <Text>-{product.discount}%</Text>}
<View>{product.title}</View>
<TouchableOpacity onPress={() => onBuy(product.id)} style={{ height: 24 }}>
<Text>Купить</Text>
</TouchableOpacity>
</View>
);
});
Коротко
Классические ошибки перехода с веба: текст вне Text, ожидание наследования стилей, && с числом, картинка без размеров. Плюс платформенные тени и снимок размеров вместо хука.
Что должен найти ревьюер
- Ошибкастрока 2
Dimensions.getдаёт снимок и не обновится при повороте или split view: нуженuseWindowDimensions. - Ошибкастрока 4
colorуViewничего не делает, текст его не наследует. Тень черезshadowOpacityработает только на iOS, на Android нуженelevationилиboxShadow. - Производительностьстрока 4Инлайновые объекты стилей создаются в каждом рендере. Вынести в
StyleSheet.create. - Ошибкастрока 5У удалённой картинки нет размеров: она не отобразится. Нужны
width/heightилиaspectRatio. - Ошибкастрока 6При
discount === 0выражение0 && ...отрендерит0внеTextи упадёт. Использовать явное сравнениеproduct.discount > 0 ? ... : null. - Ошибкастрока 7Строка внутри
View: ошибка «Text strings must be rendered within a <Text>». - Стильстрока 8Кнопка высотой 24 слишком мала для пальца, нет
accessibilityRoleи подписи. Минимум около 44 точек илиhitSlop.
Разбор
Классические ошибки перехода с веба: текст вне Text, ожидание наследования стилей, && с числом, картинка без размеров. Плюс платформенные тени и снимок размеров вместо хука.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.