const lines = [1, 2, 3];
return lines.map(line => (
<p> {line} </p>
));
function Component() {
const [lines, setLines] = useState([1, 2, 3]);
const addLine = useCallback(() => {
setLines(lines => [...lines, lines.length+1])
});
return(
<>
<button onClick={addLine} className="button">
addLine
</button>
{lines.map(line => (
<p> {line} </p>
))}
</>
}
setTimeout
(тут я обернул его в Promise
для простоты и наглядности):const delay = (ms) => new Promise(r => setTimeout(r, ms))
function Component() {
const [lines, setLines] = useState([]);
const addLines = useCallback(async () => {
let i = 0;
while(i++ < 10) {
await delay(1000);
setLines(lines => [...lines, i])
}
});
return(
<>
<button onClick={addLines} className="button">
addLine
</button>
{lines.map(line => (
<p> {line} </p>
))}
</>
);
}
function manualSmoothScroll(event) {
// находим хэш ссылу по которой мы кликнули
const id = event.target.closest('a[href^="#"]')?.hash;
// если клик куда-то ещё - ничего не делаем
if (!id) return;
// находим цель куда будем скроллить по хэшу
const target = document.querySelector(id);
// если не нашли - ничего не делаем
if (!target) return;
// отменяем стандартный переход
event.preventDefault();
// едем руками
target.scrollIntoView({ behavior: "smooth" });
}
// при загрузке
addEventListener('click', manualSmoothScroll, true);
// при выгрузке
removeEventListener('click', manualSmoothScroll, true);
// если действовать надо только в рамках элнметата
// elementRef.value.addEvent... elementRef.value.removeve...
// или this.$refs.element...
// или this.$el...
fetch
в котором у Request
body
- это ReadableStream
, растянув таким образом запрос настолько - насколько надо. Но это всё же не совсем то же самое что просто медленный запрос.{
path: '/catalog/mebel',
children: [
{
path: 'page-:page(\\d+)?',
alias: '',
component: Mebel,
},
{
path: ':category',
children: [
{
path: 'page-:page(\\d+)?',
alias: '',
component: MebelCategory
},
{
path: ':article',
component: MebelArticle
}
]
},
],
}
function useState(initialValue) {
// подсчитываем вызовы useState в компоненте
component.useStateCount++;
// если уже был вызов этого useState(т.е. это не первая отрисовка)
if (component.useStateCount in component.useStateCache)
// возвращаем результат из кэша
return component.useStateCache[component.useStateCount];
// если первый вызов - подготавливаем ответ вида [state, setState]
const useStateResult = [
initialValue,
function setState(callbackOrValue) {
// если аргумент setState - функция
if (typeof callbackOrValue === 'function') {
// вызываем её с предыдущем значением в качестве аргумента и присваиваем результат вызова в state
useStateResult[0] = callbackOrValue(useStateResult[0]);
} else {
// иначе просто присваиваем аргумент в state
useStateResult[0] = callbackOrValue;
}
// вызов обновления компонента
component.updateComounent();
}
];
// добавляем в кэш
component.useStateCache[component.useStateCount] = useStateResult;
// возвращаем
return useStateResult;
}
if (error.value?.statusCode !== 404)
не гарантирует, что в user
не будет null
, мало ли там ошибка 50х
или даже нет ошибки, а просто сервер глюканул.if (!user) {
throw new Error('empty responce')
}
useFetch
которая внутри себя скастует тип по новому или изменение самого типа useFetch
. pushState
и реакцией на popstate
. картинка.src = e.target.result
картинка.onloadend = function()
{
var width = картинка.naturalWidth
var height = картинка.naturalHeight
var соотношение = width/height
картинка.src = создать_картинку(картинка, 1000, 1000/соотношение)
}