2021-07-26 02:25:49 +09:00
# Práticas recomendadas da base de código
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
## JavaScript em geral
2021-07-08 15:09:56 +05:30
2021-08-27 09:23:06 -07:00
Na maioria dos casos, nosso [linter ](how-to-setup-freecodecamp-locally.md#follow-these-steps-to-get-your-development-environment-ready ) avisará sobre qualquer formatação que contradiga as práticas recomendadas desta base de código.
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
Recomendamos o uso de componentes funcionais em vez de componentes baseados em classes.
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
## TypeScript em específico
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
### Migração de um arquivo JavaScript para TypeScript
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
#### Manutenção do histórico de arquivos do Git
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
Algumas vezes, alterar o arquivo de `<filename>.js` para `<filename>.ts` (ou `.tsx` ) faz com que o arquivo original seja excluído e que um novo arquivo seja criado. Em outras situações simplesmente muda – nos termos do Git. O ideal é preservarmos o histórico dos arquivos.
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
A melhor maneira de conseguir isso é:
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
1. Renomear o arquivo
2. Fazer o commit com a flag `--no-verify` para evitar que o Husky reclame de erros de lint
3. Refatorar o TypeScript para migração em um commit em separado
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
> [!NOTE] Editores como o VSCode provavelmente mostrarão a você que o arquivo foi excluído e que um novo arquivo foi criado. Se você utilizar a CLI para `git add .`, o VSCode mostrará o arquivo como renomeado na fase de stage
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
### Convenções de nomes
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
#### Interfaces e tipos
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
Na maioria dos casos, recomendamos usar declarações de interface em vez de declarações de tipo.
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
Props de componentes do React – sufixo com `Props`
2021-07-08 15:09:56 +05:30
```typescript
interface MyComponentProps {}
// type MyComponentProps = {};
const MyComponent = (props: MyComponentProps) => {};
```
2021-07-26 02:25:49 +09:00
Componentes stateful do React – sufixo com `State`
2021-07-08 15:09:56 +05:30
```typescript
interface MyComponentState {}
// type MyComponentState = {};
class MyComponent extends Component< MyComponentProps , MyComponentState > {}
```
2021-07-26 02:25:49 +09:00
Padrão – nome do objeto em PascalCase
2021-07-08 15:09:56 +05:30
```typescript
interface MyObject {}
// type MyObject = {};
const myObject: MyObject = {};
```
<!-- #### Redux Actions -->
<!-- TODO: Once refactored to TS, showcase naming convention for Reducers/Actions and how to type dispatch funcs -->
## Redux
2021-07-26 02:25:49 +09:00
### Definições de ações
2021-07-08 15:09:56 +05:30
```typescript
enum AppActionTypes = {
actionFunction = 'actionFunction'
}
export const actionFunction = (
arg: Arg
): ReducerPayload< AppActionTypes.actionFunction > => ({
type: AppActionTypes.actionFunction,
payload: arg
});
```
2021-07-26 02:25:49 +09:00
### Como fazer a redução
2021-07-08 15:09:56 +05:30
```typescript
2021-07-26 02:25:49 +09:00
// Ação de redução de base sem payload
2021-07-08 15:09:56 +05:30
type ReducerBase< T > = { type: T };
2021-07-26 02:25:49 +09:00
// Lógica para lidar com os payloads opcionais
2021-07-08 15:09:56 +05:30
type ReducerPayload< T extends AppActionTypes > =
T extends AppActionTypes.actionFunction
? ReducerBase< T > & {
payload: AppState['property'];
}
: ReducerBase< T > ;
2021-07-26 02:25:49 +09:00
// Trocar o redutor exportado pelos combineReducers do Redux
2021-07-08 15:09:56 +05:30
export const reducer = (
state: AppState = initialState,
action: ReducerPayload< AppActionTypes >
): AppState => {
switch (action.type) {
case AppActionTypes.actionFunction:
return { ...state, property: action.payload };
default:
return state;
}
};
```
2021-07-26 02:25:49 +09:00
### Como fazer o dispatch
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
Em um componente, importe as ações e os seletores necessários.
2021-07-08 15:09:56 +05:30
```tsx
2021-07-26 02:25:49 +09:00
// Adicione a definição de tipo
2021-07-08 15:09:56 +05:30
interface MyComponentProps {
actionFunction: typeof actionFunction;
}
2021-07-26 02:25:49 +09:00
// Conecte à store do Redux
2021-07-08 15:09:56 +05:30
const mapDispatchToProps = {
actionFunction
};
2021-07-26 02:25:49 +09:00
// Exemplo de componente do React conectado à store
2021-07-08 15:09:56 +05:30
const MyComponent = ({ actionFunction }: MyComponentProps): JSX.Element => {
const handleClick = () => {
2021-07-26 02:25:49 +09:00
// Função de dispatch
2021-07-08 15:09:56 +05:30
actionFunction();
};
return < button onClick = {handleClick} > freeCodeCamp is awesome!< / button > ;
};
export default connect(null, mapDispatchToProps)(MyComponent);
```
<!-- ### Redux Types File -->
<!-- The types associated with the Redux store state are located in `client/src/redux/types.ts` ... -->
2021-07-26 02:25:49 +09:00
## Mais informações
2021-07-08 15:09:56 +05:30
2021-07-26 02:25:49 +09:00
- [Documentação do TypeScript ](https://www.typescriptlang.org/docs/ )
- [TypeScript com a cheatsheet do React ](https://github.com/typescript-cheatsheets/react#readme )