Created by Github action --------- Co-authored-by: Crowdin Bot <support+bot@crowdin.com> Co-authored-by: github-actions <github-actions@twenty.com>
296 lines
5.9 KiB
Plaintext
296 lines
5.9 KiB
Plaintext
---
|
|
title: crwdns60388:0crwdne60388:0
|
|
image: crwdns60390:0crwdne60390:0
|
|
---
|
|
|
|
<Frame>
|
|
<img src="/images/user-guide/notes/notes_header.png" alt="Header" />
|
|
</Frame>
|
|
|
|
crwdns60392:0crwdne60392:0
|
|
|
|
crwdns60394:0crwdne60394:0
|
|
|
|
crwdns60396:0crwdne60396:0
|
|
|
|
crwdns60398:0crwdne60398:0
|
|
|
|
crwdns60400:0crwdne60400:0
|
|
|
|
## crwdns60402:0crwdne60402:0
|
|
|
|
### crwdns60404:0crwdne60404:0
|
|
|
|
crwdns60406:0crwdne60406:0
|
|
|
|
crwdns60408:0crwdne60408:0
|
|
|
|
```tsx
|
|
// ❌ Bad, harder to read, harder to import with code completion
|
|
const MyComponent = () => {
|
|
return <div>Hello World</div>;
|
|
};
|
|
|
|
export default MyComponent;
|
|
|
|
// ✅ Good, easy to read, easy to import with code completion
|
|
export function MyComponent() {
|
|
return <div>Hello World</div>;
|
|
};
|
|
```
|
|
|
|
### crwdns60410:0crwdne60410:0
|
|
|
|
crwdns60412:0crwdne60412:0
|
|
|
|
crwdns60414:0crwdne60414:0
|
|
|
|
```tsx
|
|
// ❌ Bad, no type
|
|
export const MyComponent = (props) => <div>Hello {props.name}</div>;
|
|
|
|
// ✅ Good, type
|
|
type MyComponentProps = {
|
|
name: string;
|
|
};
|
|
|
|
export const MyComponent = ({ name }: MyComponentProps) => <div>Hello {name}</div>;
|
|
```
|
|
|
|
#### crwdns60416:0crwdne60416:0
|
|
|
|
```tsx
|
|
/* ❌ - Bad, defines the component type annotations with `FC`
|
|
* - With `React.FC`, the component implicitly accepts a `children` prop
|
|
* even if it's not defined in the prop type. This might not always be
|
|
* desirable, especially if the component doesn't intend to render
|
|
* children.
|
|
*/
|
|
const EmailField: React.FC<{
|
|
value: string;
|
|
}> = ({ value }) => <TextInput value={value} disabled fullWidth />;
|
|
```
|
|
|
|
```tsx
|
|
/* ✅ - Good, a separate type (OwnProps) is explicitly defined for the
|
|
* component's props
|
|
* - This method doesn't automatically include the children prop. If
|
|
* you want to include it, you have to specify it in OwnProps.
|
|
*/
|
|
type EmailFieldProps = {
|
|
value: string;
|
|
};
|
|
|
|
const EmailField = ({ value }: EmailFieldProps) => (
|
|
<TextInput value={value} disabled fullWidth />
|
|
);
|
|
```
|
|
|
|
#### crwdns60418:0crwdne60418:0
|
|
|
|
crwdns60420:0{...props}crwdne60420:0 crwdns60422:0crwdne60422:0
|
|
|
|
```tsx
|
|
/* ❌ - Bad, spreads a single variable prop into the underlying component
|
|
*/
|
|
const MyComponent = (props: OwnProps) => {
|
|
return <OtherComponent {...props} />;
|
|
}
|
|
```
|
|
|
|
```tsx
|
|
/* ✅ - Good, Explicitly lists all props
|
|
* - Enhances readability and maintainability
|
|
*/
|
|
const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => {
|
|
return <OtherComponent {...{ prop1, prop2, prop3 }} />;
|
|
};
|
|
```
|
|
|
|
crwdns60424:0crwdne60424:0
|
|
|
|
- crwdns60426:0crwdne60426:0
|
|
- crwdns60428:0crwdne60428:0
|
|
- crwdns60430:0crwdne60430:0
|
|
|
|
## crwdns60432:0crwdne60432:0
|
|
|
|
### crwdns60434:0crwdne60434:0
|
|
|
|
```tsx
|
|
// ❌ Bad, can return 'default' even if value is 0 or ''
|
|
const value = process.env.MY_VALUE || 'default';
|
|
|
|
// ✅ Good, will return 'default' only if value is null or undefined
|
|
const value = process.env.MY_VALUE ?? 'default';
|
|
```
|
|
|
|
### crwdns60436:0crwdne60436:0
|
|
|
|
```tsx
|
|
// ❌ Bad
|
|
onClick && onClick();
|
|
|
|
// ✅ Good
|
|
onClick?.();
|
|
```
|
|
|
|
## crwdns60438:0crwdne60438:0
|
|
|
|
### crwdns60440:0crwdne60440:0
|
|
|
|
crwdns60442:0crwdne60442:0
|
|
|
|
```tsx
|
|
// ❌ Bad
|
|
interface MyInterface {
|
|
name: string;
|
|
}
|
|
|
|
// ✅ Good
|
|
type MyType = {
|
|
name: string;
|
|
};
|
|
```
|
|
|
|
### crwdns60444:0crwdne60444:0
|
|
|
|
crwdns60446:0https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-typescrwdne60446:0 crwdns60448:0crwdne60448:0
|
|
|
|
crwdns60450:0https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enumscrwdne60450:0
|
|
|
|
```tsx
|
|
// ❌ Bad, utilizes an enum
|
|
enum Color {
|
|
Red = "red",
|
|
Green = "green",
|
|
Blue = "blue",
|
|
}
|
|
|
|
let color = Color.Red;
|
|
```
|
|
|
|
```tsx
|
|
// ✅ Good, utilizes a string literal
|
|
|
|
let color: "red" | "green" | "blue" = "red";
|
|
```
|
|
|
|
#### crwdns60452:0crwdne60452:0
|
|
|
|
crwdns60454:0crwdne60454:0
|
|
|
|
crwdns60456:0crwdne60456:0
|
|
|
|
crwdns60458:0crwdne60458:0
|
|
|
|
```TSX
|
|
const {
|
|
setHotkeyScopeAndMemorizePreviousScope,
|
|
goBackToPreviousHotkeyScope,
|
|
} = usePreviousHotkeyScope();
|
|
|
|
setHotkeyScopeAndMemorizePreviousScope(
|
|
RelationPickerHotkeyScope.RelationPicker,
|
|
);
|
|
```
|
|
|
|
## crwdns60460:0crwdne60460:0
|
|
|
|
### crwdns60462:0crwdne60462:0
|
|
|
|
crwdns60464:0https://emotion.sh/docs/styledcrwdne60464:0
|
|
|
|
```tsx
|
|
// ❌ Bad
|
|
<div className="my-class">Hello World</div>
|
|
```
|
|
|
|
```tsx
|
|
// ✅ Good
|
|
const StyledTitle = styled.div`
|
|
color: red;
|
|
`;
|
|
```
|
|
|
|
crwdns60466:0crwdne60466:0
|
|
|
|
```tsx
|
|
// ❌ Bad
|
|
const Title = styled.div`
|
|
color: red;
|
|
`;
|
|
```
|
|
|
|
```tsx
|
|
// ✅ Good
|
|
const StyledTitle = styled.div`
|
|
color: red;
|
|
`;
|
|
```
|
|
|
|
### crwdns60468:0crwdne60468:0
|
|
|
|
crwdns60470:0crwdne60470:0
|
|
|
|
#### crwdns60472:0crwdne60472:0
|
|
|
|
crwdns60474:0crwdne60474:0 crwdns60476:0crwdne60476:0
|
|
|
|
#### crwdns60478:0crwdne60478:0
|
|
|
|
crwdns60480:0crwdne60480:0 crwdns60482:0crwdne60482:0
|
|
|
|
```tsx
|
|
// ❌ Bad, directly specifies style values without utilizing the theme
|
|
const StyledButton = styled.button`
|
|
color: #333333;
|
|
font-size: 1rem;
|
|
font-weight: 400;
|
|
margin-left: 4px;
|
|
border-radius: 50px;
|
|
`;
|
|
```
|
|
|
|
```tsx
|
|
// ✅ Good, utilizes the theme
|
|
const StyledButton = styled.button`
|
|
color: ${({ theme }) => theme.font.color.primary};
|
|
font-size: ${({ theme }) => theme.font.size.md};
|
|
font-weight: ${({ theme }) => theme.font.weight.regular};
|
|
margin-left: ${({ theme }) => theme.spacing(1)};
|
|
border-radius: ${({ theme }) => theme.border.rounded};
|
|
`;
|
|
```
|
|
|
|
## crwdns60484:0crwdne60484:0
|
|
|
|
crwdns60486:0crwdne60486:0 crwdns60488:0crwdne60488:0 crwdns60490:0crwdne60490:0
|
|
|
|
```tsx
|
|
// ❌ Bad
|
|
import { type Meta, type StoryObj } from '@storybook/react';
|
|
|
|
// ❌ Bad
|
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
|
|
// ✅ Good
|
|
import { Meta, StoryObj } from '@storybook/react';
|
|
```
|
|
|
|
### crwdns60492:0crwdne60492:0
|
|
|
|
- crwdns60494:0crwdne60494:0
|
|
|
|
- crwdns60496:0crwdne60496:0 crwdns60498:0crwdne60498:0
|
|
|
|
- crwdns60500:0crwdne60500:0
|
|
|
|
### crwdns60502:0crwdne60502:0
|
|
|
|
crwdns60504:0crwdne60504:0 crwdns60506:0crwdne60506:0
|
|
|
|
crwdns60508:0crwdne60508:0 crwdns60510:0https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.htmlcrwdne60510:0 crwdns60512:0crwdne60512:0
|
|
|
|
crwdns60514:0crwdne60514:0
|