在子组件内有:
// 滚动
useEffect(() => {
if(props.scrollToIdx) {
const scrollToIdx = props.scrollToIdx
console.log("滚动ID:", '#item-' + scrollToIdx!.toString())
scrollTo(scrollToIdx)
}
}, [props.scrollToIdx])
const scrollTo = (scrollToIdx: number) => {
const container = document.querySelector("#container")
const div: HTMLDivElement | null = document.querySelector('#item-' + scrollToIdx!.toString())
console.log(container, div)
if(container) {
container.scrollTo({
top: div!.offsetTop,
behavior: 'smooth'
});
}
}
在父组件
点击按钮时候会滑动:
const btnClick = () => {
console.log('点击按钮')
setSelIdx(20)
}
return (
<div className="App">
<SubContainer {...props}></SubContainer>
<button onClick={btnClick}>点击</button>
</div>
);
但是比如我在点击一次setSelIdx(20)之后,再点击,执行:
setSelIdx(20)
子组件就不会更新再继续执行这个代码了:
useEffect(() => {
if(props.scrollToIdx) {
const scrollToIdx = props.scrollToIdx
console.log("滚动ID:", '#item-' + scrollToIdx!.toString())
scrollTo(scrollToIdx)
}
}, [props.scrollToIdx])
也就是说:props.scrollToIdx 没有更新这里就不会执行,请问要如何保证父组件点击(btnClick ... setSelIdx(20))
子组件这里每次都执行?
为了确保 useEffect
钩子在 props.scrollToIdx
更改时总是执行,你需要确保 props.scrollToIdx
的值在每次点击时确实发生了变化。从你的描述来看,问题可能出在 props.scrollToIdx
的值在第二次点击时并没有真正改变(即它仍然是 20
),因此 React 认为依赖项没有变化,因此不会重新运行 useEffect
。
要解决这个问题,你可以考虑以下几种方法:
props.scrollToIdx
的值在每次点击时都不同:scrollToIdx
总是指向同一个值(如 20
),则 useEffect
不会重新运行。你可以通过添加一个时间戳或递增的计数器来确保每次 scrollToIdx
都不同。useState
和 useEffect
在子组件中控制滚动:useState
来控制滚动,而不是直接从 props
中获取。props.scrollToIdx
的值在父组件中,你可以添加一个额外的状态来确保 scrollToIdx
每次都不同:
const [scrollCounter, setScrollCounter] = useState(0);
const btnClick = () => {
console.log('点击按钮');
setSelIdx(20);
setScrollCounter(prev => prev + 1); // 更新计数器
}
// 传递 scrollCounter 或结合 selIdx 和 scrollCounter 作为新的 prop
return (
<div className="App">
<SubContainer scrollToIdx={[selIdx, scrollCounter]}></SubContainer>
<button onClick={btnClick}>点击</button>
</div>
);
然后在子组件中,你需要相应地调整 useEffect
依赖项和滚动逻辑。
useState
在子组件中,你可以使用 useState
来存储 scrollToIdx
的值,并在父组件触发时更新它:
// 子组件
const [localScrollToIdx, setLocalScrollToIdx] = useState(props.initialScrollToIdx || null);
useEffect(() => {
if (props.scrollToIdx !== undefined) {
setLocalScrollToIdx(props.scrollToIdx);
}
}, [props.scrollToIdx]);
useEffect(() => {
if (localScrollToIdx) {
console.log("滚动ID:", '#item-' + localScrollToIdx.toString());
scrollTo(localScrollToIdx);
}
}, [localScrollToIdx]);
// ... 其余代码 ...
在父组件中,你只需传递初始的 scrollToIdx
(如果需要的话),并在需要时更新它:
const [selIdx, setSelIdx] = useState(null);
const btnClick = () => {
console.log('点击按钮');
setSelIdx(20);
}
return (
<div className="App">
<SubContainer initialScrollToIdx={selIdx}></SubContainer>
<button onClick={btnClick}>点击</button>
</div>
);
这样,每次 selIdx
更新时,都会通过 props
传递给子组件,子组件的 useEffect
钩子将检测到 props.initialScrollToIdx
的变化(如果作为依赖项),但更推荐的做法是使用内部状态 localScrollToIdx
来控制滚动行为。
在进行单元测试时,执行一个测试类就要启动springboot项目,加载上下文数据,每次执行一次测试都要再重新加载上下文环境.这样导致每一次单元测试时都会花3-5分钟时间。如何解决这个问题? 网上找不到什么简单的可行方案
vue3 中说 createApp 只能调用一次,可是我现在有两个场景需要手动挂载 组件的情况: 场景一 手动挂载弹窗,比如我手动挂载一个按钮组件: vue3 中不再支持 extend, 因此我使用createApp代替,可是第二次调用createApp的返回值和第一次调用的返回值不同,第二次的返回值没有umount方法,挂载后无法手动卸载应用。 场景二 有你一个表格,我使用render函数自定义
vue2开发 需求是没间隔多上时间请获取一次token、token是10分钟有效、我需要在7分钟的时候刷新一次token、然后我使用的是setInterval()方法 没7分钟请求一次, 但是出现的问题是、页面刷线以后setInterval()方法又重新执行了一次、导致没有正常刷新token 如何解决setInterval页面刷新以后不再重新执行 或者利用其他方法
uniapp 为什么每次进来都会执行onLoad钩子? 症状:不管是第一次还是第N次进去都会执行onload,印象中应该只有第一次进来才会执行一次吧,有谁遇到过吗,难道是用redirectTo跳转才会这样吗
用的是vue-element-admin架子. 点击一个菜单连接后打开一个列表(A.create), 点击列表中的一个项(B.create)打开B页面. 再关闭B页面, 此时再回到A, 此时又执行了A页面的create方法 开发时以上操作不会触发A页面的create, 现在莫名的都create了
我正在运行带有 WSL2 的视窗 10。我正在使用带有远程 - WSL扩展名的VSCode从我的wsl文件系统中打开文件。 当我启动我的Windows笔记本电脑并打开VSCode时,我收到以下错误: 当我执行<code>wsl时。exe——关闭PowerShell中的</code>,然后重新启动Docker Desktop,一切正常。但每次笔记本电脑重启后,我都必须这样做。 远程WSL扩展版本:v