javascript - 在现代反应中起作用的反应长按并且不返回“渲染的钩子比以前的渲染更多。”?
问题描述
这里有一个解决方案......实际上有几个 - 但它们都不适用于 React 17.0.2。他们都导致
错误:渲染的钩子比上一次渲染时更多。
即使在注释中列出了修复(例如,使用 useref() 而不是 useState)。
所以我的问题是 - 我怎样才能在 React 17.0.2 和更新版本中长按/按下/点击?
我尝试修复它:
//https://stackoverflow.com/questions/48048957/react-long-press-event
import {useCallback, useRef, useState} from "react";
const useLongPress = (
onLongPress,
onClick,
{shouldPreventDefault = true, delay = 300} = {}
) => {
//const [longPressTriggered, setLongPressTriggered] = useState(false);
const longPressTriggered = useRef(false);
const timeout = useRef();
const target = useRef();
const start = useCallback(
event => {
if (shouldPreventDefault && event.target) {
event.target.addEventListener("touchend", preventDefault, {
passive: false
});
target.current = event.target;
}
timeout.current = setTimeout(() => {
onLongPress(event);
//setLongPressTriggered(true);
longPressTriggered.current = true;
}, delay);
},
[onLongPress, delay, shouldPreventDefault]
);
const clear = useCallback(
(event, shouldTriggerClick = true) => {
timeout.current && clearTimeout(timeout.current);
shouldTriggerClick && !longPressTriggered && onClick(event);
//setLongPressTriggered(false);
longPressTriggered.current = false;
if (shouldPreventDefault && target.current) {
target.current.removeEventListener("touchend", preventDefault);
}
},
[shouldPreventDefault, onClick, longPressTriggered]
);
return {
onMouseDown: e => start(e),
onTouchStart: e => start(e),
onMouseUp: e => clear(e),
onMouseLeave: e => clear(e, false),
onTouchEnd: e => clear(e)
};
};
const isTouchEvent = event => {
return "touches" in event;
};
const preventDefault = event => {
if (!isTouchEvent(event)) return;
if (event.touches.length < 2 && event.preventDefault) {
event.preventDefault();
}
};
export default useLongPress;
RandomItem.js:
import React, {useEffect, useState} from 'react';
import Item from "../components/Item";
import Loader from "../../shared/components/UI/Loader";
import {useAxiosGet} from "../../shared/hooks/HttpRequest";
import useLongPress from '../../shared/hooks/useLongPress';
function RandomItem() {
let content = null;
let item = useAxiosGet('collection');
if (item.error === true) {
content = <p>There was an error retrieving a random item.</p>
}
if (item.loading === true) {
content = <Loader/>
}
if (item.data) {
const onLongPress = useLongPress();
return (
content =
<div>
<h1 className="text-6xl font-normal leading-normal mt-0 mb-2">{item.data.name}</h1>
<Item name={item.data.name} image={item.data.filename} description={item.data.description}/>
</div>
)
}
return (
<div>
{content}
</div>
);
}
export default RandomItem;
解决方案
(未编辑的)useLongPress 函数的使用应类似于以下示例:
import React, { useState } from "react";
import "./styles.css";
import useLongPress from "./useLongPress";
export default function App() {
const [longPressCount, setlongPressCount] = useState(0)
const [clickCount, setClickCount] = useState(0)
const onLongPress = () => {
console.log('longpress is triggered');
setlongPressCount(longPressCount + 1)
};
const onClick = () => {
console.log('click is triggered')
setClickCount(clickCount + 1)
}
const defaultOptions = {
shouldPreventDefault: true,
delay: 500,
};
const longPressEvent = useLongPress(onLongPress, onClick, defaultOptions);
return (
<div className="App">
<button {...longPressEvent}>use Loooong Press</button>
<span>Long press count: {longPressCount}</span>
<span>Click count: {clickCount}</span>
</div>
);
}
一定要传入onLongPress
函数、onClick
函数和选项对象。
这是一个带有 React 17.0.2 的代码框,其中有一个工作示例useLongPress
:https ://codesandbox.io/s/uselongpress-forked-zmtem?file=/src/App.js
推荐阅读
- python - StringIO 是否在磁盘上创建文件?
- c++ - 读取二进制数据,seek 无法正常工作
- javascript - VUE-如何通过键入它的名称来改变样式
- c# - 为同一个目标使用不同的 Nlog 渲染器?
- reactjs - 反应原生重新渲染没有按预期工作
- python - 为什么我的 venv 使用的 pip 版本与我安装的不同
- pytorch - 僵尸进程不允许释放 GPU 内存
- html - 如何使用 CSS 或 jQuery 对齐网站标题
- python - 如何在其他 python 文件中使用 keras 模型?在 django
- c++ - 有没有办法使用有限的字母范围搜索 unordered_set?