Привет. Это перевод второй статьи из серии “Лучшие подходы и решения для уменьшения кода на React” автора Rahul Sharma.
Всего в данной серии 3 статьи, и найти их все вы можете по ссылкам ниже:
Не будем терять время, давайте продолжим рассмотри лучших подходов и решений для уменьшения кода. Мы начнем с простого примера.
Если в компонент не передаются дочерние элементы, используйте самозакрывающийся тэг.
Плохой код:
return <Component></Component>;
Хороший код:
return <Component />;
Не пишите функции внутри jsx элементов.
Плохой код:
return (
<div>
<button
onClick={() => {
setCount(1);
// ...
}}
>
Click
</button>
</div>
);
Хороший код:
const onClick = useCallback(() => {
setCount(1);
// ...
}, [deps]);
return (
<div>
<button onClick={onClick}>Click</button>
</div>
);
Используйте объект в хуке useState, если вам необходимо обновлять несколько состояний приложения вместе.
Избегайте использование нескольких вызов setState подряд. Это стандартная ошибка, которая может привести к ненужным ререндерам. Лучше использовать один вызов.
Плохой код:
const [count, setCount] = useState(0);
const [name, setName] = useState("");
const onClick = () => {
setTimeout(() => {
setName("John");
setCount(count + 1);
}, 1000);
};
Хороший код:
const [state, setState] = useState({
count: 0,
name: "",
});
const onClick = () => {
setTimeout(() => {
setState((prevState) => ({
...prevState,
name: "John",
count: prevState.count + 1,
}));
}, 1000);
};
Примечание: React 18 добавил автоматическую группировку, так что реакт теперь сам решает проблему нескольких одновременных обновлений.
Используйте styled-components для стилей ваших компонентов. Это хороший выбор для избегания написания css в jsx и также убирает необходимость настройки css для приложения.
Это полностью основано на личном мнении
Плохой код:
return <div style={{ backgroundColor: "red" }}></div>;
Хороший код:
const Container = styled.div`
background-color: ${({ theme }) => theme.colors.background};
padding: 1rem;
`;
Лучший код:
const getPrimaryColor = ({ theme }) => theme.colors.primary;
const getDefaultColor = ({ theme }) => theme.colors.secondary;
const Button = styled.button`
background-color: ${getPrimaryColor};
color: ${getDefaultColor};
`;
Примечание: создайте функцию для получения цвета и других стилей из темы приложения и указывайте их при стилизации компонента. Это также поможет уменьшить код.
Старайтесь избегать классовых компонентов и используйте функциональные.
Плохой код:
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
this.onClick = this.onClick.bind(this);
}
onClick = () => {
this.setState({
count: this.state.count + 1,
});
};
render() {
return <button onClick>Click me</button>;
}
}
Хороший код:
const Counter = () => {
const [count, setCount] = useState(0);
const onClick = () => setCount(count + 1);
return <button>Click me</button>;
};
Примечание: функциональные компоненты не только уменьшают время написание кода, но также и уменьшают вес собранного приложения почти на 60%.
React.memo поможет избежать ненужные ререндеры.
Плохой код:
return (
<ui>
{items.map((item) => (
<Component>{item}</Component>
))}
</ui>
);
Хороший код:
const MemoComponent = React.memo(Component);
return (
<ui>
{items.map((item) => (
<MemoComponent>{item}</MemoComponent>
))}
</ui>
);
Примечание: Используйте React.memo() с умом. Не используйте useMemo когда компонент должен часто меняться из-за изменения пропсов.
Используйте JSX сокращения при передаче Boolean переменных.
Плохой код:
return <button disabled={true}>Submit</button>;
Хороший код:
return <button disabled>Submit</button>;
Используйте тернарный оператор вместо блока if-else.
Плохой код:
if (isLoading) {
return <div>Loading...</div>;
} else {
return <div>Data</div>;
}
Хороший код:
return isLoading ? <div>Loading...</div> : <div>Data</div>;
Используйте объекты вместо switch. Я уже упоминал это в прошлой статье для reducers.
Плохой код:
switch (props.type) {
case "ADMIN":
return <Admin />;
case "USER":
return <User />;
default:
return <NotFound />;
}
Хороший код:
const componentMap = {
ADMIN: Admin,
USER: User,
NOT_FOUND: NotFound,
};
const Component = componentMap[props.type];
return <Component />;
Лучший код:
const componentMap = {
ADMIN: React.lazy(() => import("../components/Admin")),
USER: React.lazy(() => import("../components/User")),
NOT_FOUND: React.lazy(() => import("../components/NotFound")),
};
const Component = componentMap[props.type];
return <Component />;
Используйте деструктуризацию вместо передачи нескольких пропсов по имени в компонент.
(от переводчика: спорный момент, для помощи в отладке приложения лучше передавать пропсы по отдельности)
Плохой код:
const { name, age, role } = props;
return (
<>
<Component name={name} age={age} role={role} />
</>
);
Хороший код:
return (
<>
<Component {...props} />
</>
);
Нет необходимости указывать фигурные скобки при передаче строчек в компонет.
Плохой код:
return <Component name={"John"} />;
Хороший код:
return <Component name="John" />;
Не называйте пропсы как встроенные названия у react элементов, к примеру className, style.
Плохой код:
return (
<Component style="bordered">
);
Хороший код:
return (
<Component variant="bordered">
);
Не используйте else часть, если if что-то возвращает.
Плохой код:
if (props.name) {
return <div>{props.name}</div>;
} else {
return <div>No name</div>;
}
Хороший код:
if (props.name) {
return <div>{props.name}</div>;
}
return <div>No name</div>;
Используйте React.Fragment вместо создания обертки из div, span, и т.п.
Плохой код:
return (
<div>
<span>{props.name}</span>
<span>{props.age}</span>
</div>
);
Хороший код:
return (
<>
<span>{props.name}</span>
<span>{props.age}</span>
</>
);
Вы также можете передавать key проп в React.Fragment.
Плохой код:
return (
<container>
{list.map((item) => (
<div key={item.id}>
<SomeComponent />
<SomeAnotherComponent />
</div>
))}
</container>
);
Хороший код:
return (
<>
{list.map((item) => (
<React.Fragment key={item.id}>
<SomeComponent />
<SomeAnotherComponent />
</React.Fragment>
))}
</>
);
Спасибо за прочтение!
Комментарии (4)
ToTheHit
29.03.2022 09:12Был бы намного познавательнее формат «делай вот так, потому что в этом есть вот такие плюсы», как немного в пункте про классовые и функциональные компоненты. Сейчас это выглядит как информация, взятая с потолка, т.е. без объяснения причин.
P.S. Если что я не имею в виду, что все эти советы ненужные) Спасибо за перевод!)
azizoid
31.03.2022 15:45Я так понимаю, единственный минус использования css/scss/less - это то что придёться его отдельно настраивать, например, в webpack?
Sybe
Пример, где используется
React.memo
, довольно обманчивыйМемоизация работает:
Мемоизация НЕ работает:
Кейс, когда в качестве
children
в компонент прокидывается примитивный тип, как мне кажется, довольно редкий, чаще всё-таки рендерится какой-то кастомный компонент, кудаitem
передаётся черезprops
в том или ином виде – поэтому стоит помнить, что тогда мемоизация не будет работать.asnow
Полностью согласен. Про тернарки вообще вкусовщина. По мне jsx с тернарками это полное извращение