export type ApiResponse<T> =
| { errors: Array<{ [key: string]: string }> }
| { data: Array<T> }
| { text: string };
abstract class Api<T> {
protected readonly baseUrl: string;
protected readonly endPoint: string;
protected get url(): string {
return new URL(this.endPoint, this.baseUrl).toString();
}
protected constructor(baseUrl = '/', endPoint: string) {
this.baseUrl = baseUrl;
this.endPoint = endPoint;
}
protected async http({
url = '',
method = 'GET',
data = undefined,
}: RequestData): Promise<ApiResponse<T>> {
try {
const response: Response = await fetch(
(new URL(url, this.url).toString()),
{ method, body: data }
);
return await response.json();
} catch (e) {
console.error(e.message);
return { text: e.message };
} finally {
// finnally
}
}
}
class ApiPost extends Api<Post> {
constructor(baseUrl: string, endPoint: string) {
super(baseUrl, endPoint);
}
async list(count?: number): Promise<false | Array<Post>> {
const response: ApiResponse = await this.http({
url: `${count ? `?_limit=${count}` : ''}`,
});
if (Array.isArray(response))
return response;
return false;
}
}
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@*": ["./src/modules/*"]
}
}
}
остальные параметры по своему вкусуconst obj1 = { value: 'Odd' };
const obj2 = { value: 'Even' };
export const CONST_NAMES_SORT = {
[CONST_NAMES.CONST1]: obj1,
[CONST_NAMES.CONST3]: obj1,
[CONST_NAMES.CONST2]: obj2,
[CONST_NAMES.CONST4]: obj2,
};
CONST_NAMES_SORT[CONST_NAMES.CONST1].value = 'Not Odd';
console.log(CONST_NAMES_SORT[CONST_NAMES.CONST3].value); // > Not Odd
const getEnding = num => {
const rem = num % 10
if (rem === 0) return ''
if (rem === 1) return 'а'
if (rem <= 5) return 'ы'
return ''
}
{parseInt(minutes) > 0 ? (
`Осталось ${minutes} минут${getEnding(minutes)}`
) : (
`Осталось ${seconds} секунд${getEnding(seconds)}`
)}
export type Some = {
p1?: string,
p2?: string
}
function isEmpty(o: Object): boolean{
return Object.keys(o).length === 0
}
let a: Some = {},
b: Some = {p1: "Value"}
console.log(`Object <a>${ isEmpty(a) ? '' : ' not ' } empty`);
// Object <a> empty
console.log(`Object <b>${ isEmpty(b) ? '' : ' not ' } empty`);
// Object <b> not empty
const parse = float => parseFloat(float.replace(/,/g, ''));
const number = parse(objectFloat.param1) + parse(objectFloat.param2); // 2353.66
console.log(number.toLocaleString('en-US')); // 2,353.66
npm install react-transition-group
import { TransitionGroup, CSSTransition } from "react-transition-group";
<TransitionGroup className="items-section__list">
{list.map(elem => (
<CSSTransition key={elem} timeout={500} classNames="move">
<h5 key={elem}>{elem}</h5>
</CSSTransition>
))}
</TransitionGroup>
.move-enter {
opacity: 0.01;
transform: translate(-40px, 0);
}
.move-enter-active {
opacity: 1;
transform: translate(0, 0);
transition: all 500ms ease-in;
}
.move-exit {
opacity: 1;
transform: translate(0, 0);
}
.move-exit-active {
opacity: 0.01;
transform: translate(40px, 0);
transition: all 500ms ease-in;
}
const Logic = () => {
const [inputValues, setInputValues] = useState('');
console.log('1)', inputValues);
const onChangeInput = e => {
setInputValues((currentState) => {
console.log('2) current', currentState);
return e.target.value});
console.log('3)', inputValues);
};
return <View inputValues={inputValues} onChangeInput={onChangeInput} />;
};
// Будем вводить букву 'a' в инпут. В итоге в консоле получим:
// 1)"" <-- из-за useState('');
// 2) current "" <-- так как значение мы ещё не обновили, то получаем то же начальное значение из useState('');
// 3) "" <-- вызвывается ПОСЛЕ setInputValues, тем не менее, имеет ещё не обновлённое значение.
// 1) a <-- произошло изменение состояния, компонент перерисовался.
в файле /bitrix/php_interface/dbconn.php добавил константу define("BX_USE_MYSQLI", false), а в файле /bitrix/.settings.php изменил '\\Bitrix\\Main\\DB\\MysqlConnection' на '\\Bitrix\\Main\\DB\\MysqliConnection'.