4.2 KiB
Найкращі практики кодової бази
Загальний JavaScript
In most cases, our linter will warn of any formatting which goes against this codebase's preferred practice.
Рекомендується використовувати функціональні компоненти замість класових компонентів.
Specific TypeScript
Migrating a JavaScript File to TypeScript
Збереження історії файлів Git
Sometimes changing the file from <filename>.js
to <filename>.ts
(or .tsx
) causes the original file to be deleted, and a new one created, and other times the filename just changes - in terms of Git. Ideally, we want the file history to be preserved.
Найкращі умови для досягнення цього:
- Перейменувати файл
- Commit with the flag
--no-verify
to prevent Husky from complaining about the lint errors - Refactor to TypeScript for migration, in a separate commit
[!NOTE] Такі редактори, як VSCode, все одно показуватимуть, що файл видалено та створено новий. Якщо ви використовуєте
git add .
, тоді VSCode покаже файл як перейменований в процесі
Naming Conventions
Інтерфейси та типи
For the most part, it is encouraged to use interface declarations over type declarations.
React Component Props - суфікс Props
interface MyComponentProps {}
// type MyComponentProps = {};
const MyComponent = (props: MyComponentProps) => {};
React Stateful Components - суфікс State
interface MyComponentState {}
// type MyComponentState = {};
class MyComponent extends Component<MyComponentProps, MyComponentState> {}
За замовчуванням - ім'я об'єкта в PascalCase
interface MyObject {}
// type MyObject = {};
const myObject: MyObject = {};
Redux
Визначення дій
enum AppActionTypes = {
actionFunction = 'actionFunction'
}
export const actionFunction = (
arg: Arg
): ReducerPayload<AppActionTypes.actionFunction> => ({
type: AppActionTypes.actionFunction,
payload: arg
});
Як підключити Reduce
// Base reducer action without payload
type ReducerBase<T> = { type: T };
// Logic for handling optional payloads
type ReducerPayload<T extends AppActionTypes> =
T extends AppActionTypes.actionFunction
? ReducerBase<T> & {
payload: AppState['property'];
}
: ReducerBase<T>;
// Switch reducer exported to Redux combineReducers
export const reducer = (
state: AppState = initialState,
action: ReducerPayload<AppActionTypes>
): AppState => {
switch (action.type) {
case AppActionTypes.actionFunction:
return { ...state, property: action.payload };
default:
return state;
}
};
How to Dispatch
Усередині компонента імпортуйте необхідні дії та селектори.
// Add type definition
interface MyComponentProps {
actionFunction: typeof actionFunction;
}
// Connect to Redux store
const mapDispatchToProps = {
actionFunction
};
// Example React Component connected to store
const MyComponent = ({ actionFunction }: MyComponentProps): JSX.Element => {
const handleClick = () => {
// Dispatch function
actionFunction();
};
return <button onClick={handleClick}>freeCodeCamp is awesome!</button>;
};
export default connect(null, mapDispatchToProps)(MyComponent);