Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在渲染前使用React挂钩响应道具更改_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript 如何在渲染前使用React挂钩响应道具更改

Javascript 如何在渲染前使用React挂钩响应道具更改,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我试图使用一个功能组件和React钩子来实现一个简化的自动滚动器,当子内容溢出时,它会自动将容器滚动到底。但是,只有当滚动条已经位于底部时,才会发生自动滚动(例如,如果用户向上滚动以查看输出,则当新内容进入时,滚动位置不应改变) 我知道如何通过使用refs和对clientHeight、scrollTop和scrollHeight执行计算来实现自动滚动行为 我的问题是,在重新渲染组件之前,我需要计算shouldAutoScroll()检查 我的流程需要如下所示: <container>

我试图使用一个功能组件和React钩子来实现一个简化的自动滚动器,当子内容溢出时,它会自动将容器滚动到底。但是,只有当滚动条已经位于底部时,才会发生自动滚动(例如,如果用户向上滚动以查看输出,则当新内容进入时,滚动位置不应改变)

我知道如何通过使用refs和对clientHeight、scrollTop和scrollHeight执行计算来实现自动滚动行为

我的问题是,在重新渲染组件之前,我需要计算
shouldAutoScroll()
检查

我的流程需要如下所示:

<container>
   {props.children}
</container>

When props.children changes:
   1. Check if the scrollbar is near the bottom and store the result
   2. Update container to reflect the new props.children
   3. If the check from step 1 is true, scroll to the bottom
我需要保持组件的通用性,这样无论是什么类型的组件或元素props.children,它都可以自动滚动。在某些情况下,对props.chldren的更改可能是一行。在其他情况下,它可能是20行,也可能是一个图像


如果我使用的是旧样式的类组件,我可以在componentWillReceiveProps()中进行计算。我如何用钩子复制它?

我发现了一个可行的解决方案,但似乎有点混乱

解决方案是在容器的
onScroll()
事件期间计算并更新
shouldAutoScroll()
。这看起来很混乱,因为我捕获了大量无用的中间滚动信息,而我所关心的只是更新开始时(但在组件重新渲染之前)的滚动位置

完整代码:

import React, { useRef, useEffect, useLayoutEffect } from 'react';
import styles from './AutoScroller.module.scss';

export function AutoScroller({children, className=''}) {
  const classNames = `${styles.default} ${className}`;

  const containerRef = useRef(null);
  const shouldAutoScroll = useRef(false);

  function updateShouldAutoScroll(element, tolerance) {
    const {scrollHeight, scrollTop, clientHeight} = element;
    const result = scrollHeight - scrollTop <= clientHeight + tolerance;

    shouldAutoScroll.current = result;
  }

  function onContainerScroll(e) {
    updateShouldAutoScroll(e.target, 25)
  }

  useEffect(function autoScroll() {
    if (shouldAutoScroll.current) {
      const element = containerRef.current;
      element.scrollTop = element.scrollHeight;
    }
  });

  return (
    <div className={classNames} ref={containerRef} onScroll={onContainerScroll}>
      {children}
    </div>
  )
}

import React,{useRef,useffect,useLayoutEffect}来自'React';
从“/AutoScroller.module.scss”导入样式;
导出函数AutoScroller({children,className='''}){
const classNames=`${styles.default}${className}`;
const containerRef=useRef(null);
const shouldAutoScroll=useRef(false);
函数更新Shouldautoscroll(元素,公差){
常量{scrollHeight,scrollTop,clientHeight}=元素;
const result=scrollHeight-scrollTop您可以在中复制它吗?
import React, { useRef, useEffect, useLayoutEffect } from 'react';
import styles from './AutoScroller.module.scss';

export function AutoScroller({children, className=''}) {
  const classNames = `${styles.default} ${className}`;

  const containerRef = useRef(null);
  const shouldAutoScroll = useRef(false);

  function updateShouldAutoScroll(element, tolerance) {
    const {scrollHeight, scrollTop, clientHeight} = element;
    const result = scrollHeight - scrollTop <= clientHeight + tolerance;

    shouldAutoScroll.current = result;
  }

  function onContainerScroll(e) {
    updateShouldAutoScroll(e.target, 25)
  }

  useEffect(function autoScroll() {
    if (shouldAutoScroll.current) {
      const element = containerRef.current;
      element.scrollTop = element.scrollHeight;
    }
  });

  return (
    <div className={classNames} ref={containerRef} onScroll={onContainerScroll}>
      {children}
    </div>
  )
}