标签: react-ref

我们如何知道 React ref.current 值何时发生了变化?

正常情况下,有了props,我们就可以写

componentDidUpdate(oldProps) {
  if (oldProps.foo !== this.props.foo) {
    console.log('foo prop changed')
  }
}
Run Code Online (Sandbox Code Playgroud)

为了检测道具的变化。

但是如果我们使用React.createRef(),我们如何检测 ref 何时更改为新组件或 DOM 元素?React 文档并没有真正提及任何内容。

铁,

class Foo extends React.Component {
  someRef = React.createRef()

  componentDidUpdate(oldProps) {
    const refChanged = /* What do we put here? */

    if (refChanged) {
      console.log('new ref value:', this.someRef.current)
    }
  }

  render() {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

我们是否应该自己实现某种旧价值的东西?

铁,

class Foo extends React.Component {
  someRef = React.createRef()
  oldRef = {}

  componentDidMount() {
    this.oldRef.current = this.someRef.current
  }

  componentDidUpdate(oldProps) {
    const …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-ref

24
推荐指数
2
解决办法
4万
查看次数

在 useRef() 中存储回调

下面是一个可变 ref 的示例,该示例存储来自Overreacted 博客的当前回调:

function useInterval(callback, delay) {
  const savedCallback = useRef();

  // update ref before 2nd effect
  useEffect(() => {
    savedCallback.current = callback; // save the callback in a mutable ref
  });

  useEffect(() => {
    function tick() {
      // can always access the most recent callback value without callback dep 
      savedCallback.current(); 
    }

    let id = setInterval(tick, delay);
    return () => clearInterval(id);
  }, [delay]);
}
Run Code Online (Sandbox Code Playgroud)

然而,React Hook FAQ 指出不推荐使用该模式:

另请注意,此模式可能会导致并发模式出现问题。[...]

在任何一种情况下,我们都不推荐这种模式,只是为了完整起见在这里展示它。

我发现这种模式对于回调非常有用,但我不明白为什么它会在 FAQ 中出现危险信号。例如,客户端组件可以使用 …

javascript reactjs react-ref react-hooks react-concurrent

14
推荐指数
1
解决办法
1194
查看次数

为什么不能将 ref 传递给 React 中的功能组件?

为什么不能将 ref 传递给 React 中的功能组件?

与无法向其传递引用的类组件相比,函数组件有何不同?

为什么那不可能呢?

注意:我提出这个问题是因为我总是看到有关如何将 ref 与功能组件一起使用的解释,并且您需要使用fowardRef,但没有人解释 React 如何处理功能组件,从而无法将 ref 传递给它,它总是解释如何去做,但从来没有解释为什么你需要这样做。

reactjs react-ref

14
推荐指数
1
解决办法
7744
查看次数

如何正确地将节点从 ref 传递到上下文?

我正在尝试将节点从 ref 传递到上下文。但是因为我在第一次渲染后没有重新渲染,所以传递的节​​点是null. 我想到了两种变体(但我认为它们不是最好的):

  1. 通过ref而不是ref.current. 但是在用例中,我将被迫使用类似的东西contextRef.current而不是contextNode.

  2. 使用状态(像firstRender得到一个后)重新渲染的成分ref.current。这似乎不是最优的。

什么是正确的(最好的?)方法?

代码沙盒

import React, { createContext, createRef, useContext, useEffect } from "react";
import ReactDOM from "react-dom";

const Context = createContext(null);

const App = ({ children }) => {
  const ref = createRef();

  return (
    <div ref={ref}>
      <Context.Provider value={ref.current}>{children}</Context.Provider>
    </div>
  );
};

const Child = () => {
  const contextNode = useContext(Context);

  useEffect(() => {
    console.log(contextNode);
  });

  return <div />; …
Run Code Online (Sandbox Code Playgroud)

javascript reactjs react-context react-ref react-hooks

10
推荐指数
1
解决办法
4431
查看次数

React 在 Redux 中存储 Ref 元素

您会如何在 Redux 中存储 Ref 元素?您会这样做吗?

我有一个包含一些表单元素的组件,如果用户离开页面并返回,我需要存储用户在表单中选择的字段的状态。

我尝试像这样在 Redux 中注册每个输入字段(我使用的<InputGroup>是 Blueprint.js 中的组件):

<InputGroup
  inputRef={(ref) => { dispatch(addRefToState(ref)) }}
  ...more props...
/>
Run Code Online (Sandbox Code Playgroud)

这导致了循环 JSON 引用错误,因为 Redux 正在将 ref 元素序列化为 JSON,以便将其保存到 localStorage。然后,我尝试使用我在 Stackoverflow 上找到的代码片段对对象进行“安全”字符串化,在将对象转换为 JSON 之前删除所有循环引用。这种方法可行,但 Ref 元素仍然很大,以至于存储在状态中的 3-5 个引用变成了 3MB 的 localStorage,并且我的浏览器开始变得非常慢。此外,我担心我是否可以实际使用该 Ref 对象来引用我的组件,因为我基本上修改了 Ref 对象。我还没有尝试过,因为字符串化对象的性能非常差。

我正在考虑放弃“React 方式”,只在每个组件上添加唯一的 ID,将这些 ID 存储在 Redux 中,并使用 document.querySelector 迭代 DOM,以便在加载页面时聚焦到正确的元素。但感觉就像是黑客攻击。你会怎样做呢?

reactjs react-redux react-ref

9
推荐指数
1
解决办法
1万
查看次数

返回 input 或 textArea 的元素的 React/Typescript forwardRef 类型

我正在尝试使用 react 和 typescript 为我们的应用程序创建一个通用的文本输入组件。我希望它能够成为基于给定道具的输入元素或 textarea 元素。所以它看起来有点像这样:

import {TextArea, Input} from 'ourComponentLibrary'

export const Component = forwardRef((props, ref) => {
  const Element = props.type === 'textArea' ? TextArea : Input

  return (
    <Element ref={ref} />
  )
})
Run Code Online (Sandbox Code Playgroud)

这段代码工作正常。然而,当试图合并类型时,它变得有点冒险。ref 类型应该是HTMLInputElementHTMLTextAreaElement基于传递的typeprop。在我的脑海中,它看起来像这样:

interface Props {
  ...
}

export const Component = forwardRef<
  HTMLInputElement | HTMLTextAreaElement,
  Props
>((props, ref) => {
  ...
});
Run Code Online (Sandbox Code Playgroud)

但是我知道这不完全是我需要的。因此,错误: Type 'HTMLInputElement' is missing the following properties from type 'HTMLTextAreaElement': cols, rows, textLength, wrap …

typescript reactjs react-ref react-forwardref

9
推荐指数
2
解决办法
3406
查看次数

如果我们可以简单地在 props 中传递创建的 ref ,为什么我们需要 ReactforwardRef 呢?

根据 React 文档,将 ref 传递给子组件的正确方法如下:

import React from 'react';

const Input = React.forwardRef((props, ref) => {
  React.useEffect(() => {
    ref.current.focus();
  }, []);
  return <input type="text" ref={ref} />;
});

export default function App() {
  const inputRef = React.createRef();
  return (
    <div>
      <Input ref={inputRef} />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试将创建的 ref 作为普通 prop 以任何其他名称(然后是“ref”)传递,这也会按预期工作。

import React from 'react';

const Input = (props) => {
  React.useEffect(() => {
    props.inputRef.current.focus();
  }, []);
  return <input type="text" ref={props.inputRef} />;
};

export default function App() {
  const inputRef …
Run Code Online (Sandbox Code Playgroud)

reactjs react-ref react-forwardref

9
推荐指数
1
解决办法
6619
查看次数

在react中有条件地分配ref

我正在做一些反应,并遇到了一个我无法解决自己的挑战。我在这里和其他地方搜索过,发现了标题相似的主题,但与我遇到的问题没有任何关系,所以我们开始:

所以我有一个数组,它将被映射到 React 组件中,通常如下所示:

export default ParentComponent = () => {

//bunch of stuff here and there is an array called arr

return (<>
 
    {arr.map((item, id) => {<ChildComponent props={item} key={id}>})}

</>)

}
Run Code Online (Sandbox Code Playgroud)

但问题是,父元素中有一个状态,它存储当前选定的子组件之一的 id(我通过设置上下文并在子组件内设置此状态来做到这一点),然后问题是我必须引用当前选定的 ChildComponent 内部的节点。我可以毫无问题地转发引用,但我也想仅在当前选定的 ChildComponent 上分配引用,我想这样做:

export default ParentComponent = () => {

//bunch of stuff here and there is an array called arr and there's a state which holds the id of a  selected ChildComponent called selectedObjectId

const selectedRef = createRef();

return (<>
    <someContextProvider>
    {arr.map((item, id) => …
Run Code Online (Sandbox Code Playgroud)

reactjs react-ref react-hooks

8
推荐指数
2
解决办法
1万
查看次数

ref scrollIntoView 不适用于反应上的平滑行为

我正在创建一个组件,该组件将保存动态元素列表,出于样式原因,我需要将每个部分的标题保留在粘性导航菜单中。当用户上下滚动部分列表时,我需要应用样式规则,并将菜单导航中的同一部分带入视图,因此我尝试将scrollIntoView与菜单部分引用一起使用。

我的内部工作和逻辑似乎按预期工作,但是存在一个问题 - 除非我检查或在页面上使用刷新,否则scrollIntoView的函数不会在每次状态更改时执行

const scrollTo = (ref) => {
  ref.current.scrollIntoView({ behavior: "smooth", inline: "center" });
};
Run Code Online (Sandbox Code Playgroud)

为了简单起见,我已将我的工作添加到此codesandbox中

任何帮助将不胜感激,因为我已经没有想法了。

谢谢

编辑:

如果我从scrollIntoViewOptions选项中删除行为参数中的“smooth”选项,滚动行为似乎会按预期工作。然而它看起来确实很神经质。

const scrollToMenu = (ref) => {
  ref.current.scrollIntoView({ inline: "center", });
};
Run Code Online (Sandbox Code Playgroud)

reactjs js-scrollintoview react-ref react-usememo react-scroll

8
推荐指数
1
解决办法
5784
查看次数

解构嵌套对象:如何获取父级及其子级值?

在下面的函数中,我得到了带有属性的textarea对象current.

这里,嵌套的解构与StartEnd变量一起工作.但current变量不起作用.

function someFunction({ current: { selectionStart: Start, selectionEnd: End } }, AppStateSetter) {

    // do something with current, Start, and End
}
Run Code Online (Sandbox Code Playgroud)

javascript destructuring reactjs react-ref

7
推荐指数
1
解决办法
715
查看次数