reactjs - 在功能组件上设置 ref
问题描述
我正在尝试将这个基于类的反应组件更改为功能组件,但我在设置引用时遇到了一个无限循环问题,我认为这是因为在每次渲染时,引用都是一个新对象。
我如何将基于类的组件转换为功能组件
index-class.js -参考
class Collapse extends React.Component {
constructor(props) {
super(props);
this.state = {
showContent: false,
height: "0px",
myRef: null,
};
}
componentDidUpdate = (prevProps, prevState) => {
if (prevState.height === "auto" && this.state.height !== "auto") {
setTimeout(() => this.setState({ height: "0px" }), 1);
}
}
setInnerRef = (ref) => this.setState({ myRef: ref });
toggleOpenClose = () => this.setState({
showContent: !this.state.showContent,
height: this.state.myRef.scrollHeight,
});
updateAfterTransition = () => {
if (this.state.showContent) {
this.setState({ height: "auto" });
}
};
render() {
const { title, children } = this.props;
return (
<div>
<h2 onClick={() => this.toggleOpenClose()}>
Example
</h2>
<div
ref={this.setInnerRef}
onTransitionEnd={() => this.updateAfterTransition()}
style={{
height: this.state.height,
overflow: "hidden",
transition: "height 250ms linear 0s",
}}
>
{children}
</div>
</div>
);
}
}
到目前为止我所尝试的。
索引功能.js
import React, { useEffect, useState } from "react";
import { usePrevious } from "./usePrevious";
const Collapse = (props) => {
const { title, children } = props || {};
const [state, setState] = useState({
showContent: false,
height: "0px",
myRef: null
});
const previousHeight = usePrevious(state.height);
useEffect(() => {
if (previousHeight === "auto" && state.height !== "auto") {
setTimeout(
() => setState((prevState) => ({ ...prevState, height: "0px" })),
1
);
}
}, [previousHeight, state.height]);
const setInnerRef = (ref) =>
setState((prevState) => ({ ...prevState, myRef: ref }));
const toggleOpenClose = () =>
setState((prevState) => ({
...prevState,
showContent: !state.showContent,
height: state.myRef.scrollHeight
}));
const updateAfterTransition = () => {
if (state.showContent) {
this.setState((prevState) => ({ ...prevState, height: "auto" }));
}
};
return (
<div>
<h2 onClick={toggleOpenClose}>{title}</h2>
<div
ref={setInnerRef}
onTransitionEnd={updateAfterTransition}
style={{
height: state.height,
overflow: "hidden",
transition: "height 250ms linear 0s"
}}
>
{children}
</div>
</div>
);
};
usePrevious.js -链接
import { useRef, useEffect } from "react";
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
export { usePrevious };
解决方案
这里的问题是您通过 setState 和 useEffect 将引用设置为更新(这就是导致无限循环的原因)。
通过在功能组件上设置引用的方式如下:
const Component = () => {
const ref = useRef(null)
return (
<div ref={ref} />
)
}
更多信息可以在这里找到:https ://reactjs.org/docs/refs-and-the-dom.html
推荐阅读
- python - 为什么将外键字段添加到模型后 URL 不起作用?
- flutter - 我想要 Flutter 应用程序中的 Microsoft 身份验证
- python-3.x - Django:'TypeError:'HttpResponseForbidden'对象不可调用
- netsuite - NetSuite:在字段值更新时实时调用 API
- laravel - Eloquent 模型 save() 内存不足
- python - 如何在不更改 Python 中颜色条大小的情况下更改我的 cmap 图形的大小?
- javascript - 如何让脚本解析下一页的内容?
- elasticsearch - ApiKey 与 role_descriptors 访问 Kibana
- javascript - 如何检查任何字符串是否包含Node中的sql注入
- google-bigquery - 保存解析 json 文件的输出并将其传递给 Bigqueryinsertjoboperator