Javascript 用钩子编写这个React类组件的更好方法是什么?
我有一个固定高度的部分。我不知道组件什么时候挂载(第一次呈现)进来的内容是否合适。如果它不适合,那么我需要渲染一个“阅读更多”按钮 看起来是这样的: 我最初是使用生命周期方法DidMount/diddupdate作为类组件编写的: 类组件 我很惊讶,我需要添加另一个状态(userClicked),这就是我强制第二次渲染的方式(即,相当于类解决方案中的Javascript 用钩子编写这个React类组件的更好方法是什么?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有一个固定高度的部分。我不知道组件什么时候挂载(第一次呈现)进来的内容是否合适。如果它不适合,那么我需要渲染一个“阅读更多”按钮 看起来是这样的: 我最初是使用生命周期方法DidMount/diddupdate作为类组件编写的: 类组件 我很惊讶,我需要添加另一个状态(userClicked),这就是我强制第二次渲染的方式(即,相当于类解决方案中的componentdiddupdate) 这是正确的还是有人能找到一种更简洁的方法来编写第二个解决方案 注意 我询问的原因之一是,在控制台中,我收
componentdiddupdate
)
这是正确的还是有人能找到一种更简洁的方法来编写第二个解决方案
注意
我询问的原因之一是,在控制台中,我收到以下警告:
我不想将它们添加到依赖项数组中,因为我不想在它们更改时触发渲染…?您可以添加一个额外的
useffect(()=>(…),[])
,其作用类似于componentDidMount()
。还有另一个useffect(()=>(…)
,其作用类似于componentdiddupdate()
。然后您应该能够摆脱userClicked
这是一个关于生活方式方法如何与钩子一起工作的好链接
如果您希望在布局之后进行更新,则第二个选项可能需要是
useLayoutEffect
。我非常喜欢解决查询
以下是实施方案:
首先,我想到的是
useEffect(() => {
setOverflowActive(isOverflowing(wrapper.current));
}, [wrapper]);
但如果我们这样做,它将再次调用useEffect,就像我们单击“阅读更多”按钮一样。因为它比较的是包装器的引用,而不是它的值
因此,为了避免引用比较,我们必须使用useCallback钩子
const isOverflowingNode = node => {
return node.offsetHeight < node.scrollHeight;
};
const wrapper = useCallback(node => {
if (node !== null) {
setOverflowActive(isOverflowingNode(node));
}
}, []);
const isOverflowingNode=node=>{
返回node.offsetHeight{
如果(节点!==null){
setOverflowActive(IsOverflowNode(node));
}
}, []);
我遇到了一个美妙的讨论:
有关更多信息:
谢谢你的提问:)你能为你的第二种方法创建一个代码沙盒()或其他东西吗?如果需要的话,我会更容易重构它。好的,我可以试试。请给我一些时间,因为我以前没有这样做过,因为这将很简单,只需为此代码创建一个示例/模拟。因此,我们可以玩一些东西:)@ManishSundriyal我添加了代码,但是由于所有数据都是从GraphQL查询动态加载的,如果我不模拟所有数据,代码就不会在沙箱中运行data@ManishSundriyal好的,在沙盒中运行:谢谢,好主意,但遗憾的是,这不起作用(即使使用useLayoutEffect)-控制台警告无限的事件链:(
48:6 warning React Hook useEffect has missing dependencies:
'overflowActive' and 'wrapper'. Either include them or remove the
dependency array react-hooks/exhaustive-deps
useEffect(() => {
setOverflowActive(isOverflowing(wrapper.current));
}, []);
useEffect(() => {
if (!overflowActive && wrapper.current) {
setOverflowActive(isOverflowing(wrapper.current))
}
});
useEffect(() => {
setOverflowActive(isOverflowing(wrapper.current));
}, [wrapper]);
const isOverflowingNode = node => {
return node.offsetHeight < node.scrollHeight;
};
const wrapper = useCallback(node => {
if (node !== null) {
setOverflowActive(isOverflowingNode(node));
}
}, []);