简体   繁体   English

React - 如何跟踪 useRef 孩子的变化

[英]React - How to track useRef children change

I have a component ( Comp ) that I've added a useRef ( compRef ) to its parameters.我有一个组件 ( Comp ),我在其参数中添加了一个useRef ( compRef )。 As part of the main useEffect - I'm setting the data of this component.作为主要 useEffect 的一部分 - 我正在设置此组件的数据。 That data contains an array of strings, and the Comp displaying all of them as input s -该数据包含一个字符串数组,并且Comp将所有字符串显示为input s -

<Comp ref={compRef}>
     <input type="text"/>
</Comp>

and

data = ["HIDDEN", "data1", "data2", "data3", "data4"]

useEffect(() => { 
     compRef.current.refElement.value = data;
}, []);

so now the Comp will look like this -所以现在Comp看起来像这样 -

<Comp>
<generatedWrap> // should be hidden
    <input value="HIDDEN" />
</generatedWrap>

<generatedWrap>
    <input value="data1" />
</generatedWrap>

<generatedWrap>
    <input value="data2" />
</generatedWrap>

<generatedWrap>
    <input value="data3" />
</generatedWrap>

<generatedWrap>
    <input value="data4" />
</generatedWrap>
</Comp>

I want to hide the first input with this hide command -我想用这个hide命令隐藏第一个输入 -

compRef.current.refElement.children[0].style.display = "none";

The problem is, that with every method (useEffect) I'm using during the mount of the screen, the children are empty.问题是,对于我在安装屏幕期间使用的每种方法(useEffect),孩子都是空的。 Only after the screen is ready It's working (ie triggered by a <button> )只有在屏幕准备好后它才能工作(即由<button>触发)

I need a way to track the number of children of the ref before the view is mounted, and once it's greater than 1 to fire the hide command.我需要一种方法来在安装视图之前跟踪 ref 的子项数量,并且一旦它大于 1 就可以触发hide命令。

How can I do that?我怎样才能做到这一点?

Ok好的

So after a lot of testing - the only option I found is to add setTimeout(() => compRef.current.refElement.children[0].style.display = "none") after the render of the Comp .因此,经过大量测试 - 我发现的唯一选择是在Comp渲染后添加setTimeout(() => compRef.current.refElement.children[0].style.display = "none")

(After the render there is still only 1 child but the fact that the setTimeout is a-synchronic make it work) (渲染后仍然只有 1 个孩子,但 setTimeout 是异步的这一事实使其工作)

Thank you all for the help:)谢谢大家的帮助:)

I'm not sure if I've correctly understood the situation, but it seems odd to me.我不确定我是否正确理解了这种情况,但这对我来说似乎很奇怪。

Keep in mind that in React's paradigm, refs are more like an escape hatch, and should be avoided when possible.请记住,在 React 的范例中, refs更像是一个逃生舱,应该尽可能避免。

Also, beware that for non native components, a ref can be forwarded to any element, or be handled in any way, so it is not safe to assume it will be the root element.另外,请注意,对于非本地组件, ref可以转发到任何元素,或以任何方式处理,因此假设它将是根元素是不安全的。

In any case, you may proceed as follows:在任何情况下,您都可以进行以下操作:

<Comp>
     <input type="text" ref={(ref) => ref && (ref.parentElement.style.display = 'none')} />
</Comp>

It is the cleanest way I can think of right now with the information I have.这是我现在能想到的最干净的方式。

Please let me know if it works for you.请让我知道它是否适合您。

Update:更新:

The function in ref is called a Callback Ref . ref中的 function 称为Callback Ref It will receive the corresponding ref value as the first argument (the HTML input element in this case).它将接收相应的ref值作为第一个参数(在本例中为 HTML input元素)。

The advantage is that you don't have to detect when Comp decides to populate the DOM.优点是您不必检测Comp何时决定填充 DOM。 The callback ref will be called as soon as the real node is ready.一旦真正的节点准备好,回调 ref 就会被调用。

tldr - don't use refs to manipulate the DOM ever (unless you're an advanced react developer and know exactly what you're doing, which you aren't because these devs wouldn't be asking these questions on SO). tldr - 永远不要使用 refs 来操作 DOM (除非您是高级反应开发人员并且确切地知道自己在做什么,因为这些开发人员不会在 SO 上问这些问题)。

Don't use refs at all, you're doing React drastically wrong by manually manipulating the DOM.根本不要使用 refs,你通过手动操作 DOM 来做 React 大错特错。

Just pass the strings as props and let the component worry about displaying them:只需将字符串作为道具传递,让组件担心显示它们:

const MyParentComponent = () => {

   return <Comp data={["HIDDEN", "data1", "data2", "data3", "data4"]}/>
}

If you want to hide a certain input in that child component, then pass another prop, for example:如果您想在该子组件中隐藏某个输入,则传递另一个道具,例如:

const MyParentComponent = () => {

   const [indexToHide,setIndexToHide] = useState(0);

   return <Comp data={["HIDDEN", "data1", "data2", "data3", "data4"]} indexOfInputToHide={indexToHide}/>
}

and then just let Comp worry about it's props and that's it.然后让Comp担心它的道具,仅此而已。

It's unclear what you're trying to do so the liklihood that this is the exact code you need is not great.目前尚不清楚您要尝试做什么,因此这是您需要的确切代码的可能性并不大。 But by continuing to try and use refs and manipulate the DOM, you are fighting against the framework and will end up having a much more difficult time in the future as you're doing react wrong, even if you do manage to come up with a working solution in this case.但是,通过继续尝试使用 refs 和操作 DOM,您正在与框架作斗争,并且由于您做出错误的反应,即使您确实设法提出了一个在这种情况下的工作解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM