React Hooks - 将 ref 传递给 child 以使用 ScrollIntoView
React Hooks - Passing ref to child to use ScrollIntoView
我有两个组件。一个 parent 和一个 child.
在 parent 组件中我有一个按钮。如果用户单击该按钮,我想对 child 组件内的另一个按钮执行 ScrollIntoView。
我想我想定义对 childs 按钮 a 的引用,这样我在 parent 按钮 onClick 中可以执行 a:
ref.scrollIntoView({block: 'end', behavior: 'smooth'});
这将滚动到 child 组件中的按钮。
这是一个缩小的例子:
ParentComponent.jsx
import React, {useRef} from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = props => {
const childReference = useRef(null);
const onClick = () => {
childReference.scrollIntoView({block: 'end', behavior: 'smooth'});
}
return (
<>
<...some other components>
<Button onClick={onClick}>Click me to be forwarded</Button>
<ChildComponent ref={childReference}/>
</>
);
};
ChildComponent.jsx
import React from 'react';
const ChildComponent = (props, ref) => {
const { name, value, description } = props;
return (
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
);
};
ChildComponent.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.number,
description: PropTypes.string,
};
ChildComponent.defaultProps = {
value: 0,
description: '',
};
export default React.forwardRef(ChildComponent);
我知道上面的代码不起作用,它只是为了说明我正在努力实现的目标。
我真的尝试了通过谷歌搜索找到的所有其他解决方案,它们看起来都很简单,但其中 none 似乎适用于我的用例。我也尝试过使用 forwardRef,但这对我来说也没有解决问题。
更新
我想我对什么不起作用有点含糊。我在实施过程中收到了很多不同的错误消息。
以下为其中之一:
Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
解决方案
好的。我想我会 assemble 这里的片段与@Vencovsky 提供的解决方案。
这是问题中看到的两个示例组件的完整实现:
ParentComponent.jsx
import React, { useRef } from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = props => {
const childReference = useRef(null);
const scrollIntoView = () => {
childReference.current.scrollIntoView({block: 'center', inline: 'center', behavior: 'smooth'});
}
return (
<>
<...some other component>
<Button onClick={scrollIntoView}>Click me to be forwarded</Button>
<ChildComponent ref={childReference}
</>
);
};
export default ParentComponent;
ChildComponent.jsx
import React, {forwardRef} from 'react';
import PropTypes from 'prop-types';
const ChildComponent = forwardRef((props, ref) => {
const { name, value, description } = props;
return(
<>
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
</>
);
});
ChildComponent.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.number,
description: PropTypes.string,
};
ChildComponent.defaultProps = {
value: 0,
description: '',
};
export default ChildComponent;
编辑 2:
我猜你在做类似的事情
const ChildComponent = (props, ref) => { ... }
ChildComponent.propTypes = { ... }
export default React.forwardRef(ChildComponent)
但是你需要做的是在 React.forwardRef
之后传递 propTypes
,像这样:
const ChildComponent = (props, ref) => { ... }
const ForwardComponent = React.forwardRef(ChildComponent)
ForwardComponent.propTypes = { ... }
export default ForwardComponent
更好的方法是
// using forwarRef
const ChildComponent = React.forwarRef((props, ref) => {
const { name, value, description } = props;
return (
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
);
});
那么您就不需要更改 propTypes
并创建另一个组件。
编辑:
作为您的编辑,我看到您忘记使用 React.forwardRef
。
你应该添加
export default React.forwardRef(ChildComponent)
到您的 ChildComponent
文件(使用 forwardRef 导出)。
什么不起作用?你有错误吗?你应该更好地解释发生了什么,但我会尝试猜测。
有些东西会导致它无法正常工作。
- 您需要使用
ref.current.foo
而不是 ref.foo
- 正如@JeroenWienk 所说:
It seems that your button is also a custom component. Are you sure the ref is being passed to the html button element inside there?
- 要使用功能组件的第二个参数,您应该使用
React.forwardRef
。例如export default React.forwardRef(ChildComponent)
我有两个组件。一个 parent 和一个 child.
在 parent 组件中我有一个按钮。如果用户单击该按钮,我想对 child 组件内的另一个按钮执行 ScrollIntoView。
我想我想定义对 childs 按钮 a 的引用,这样我在 parent 按钮 onClick 中可以执行 a:
ref.scrollIntoView({block: 'end', behavior: 'smooth'});
这将滚动到 child 组件中的按钮。
这是一个缩小的例子:
ParentComponent.jsx
import React, {useRef} from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = props => {
const childReference = useRef(null);
const onClick = () => {
childReference.scrollIntoView({block: 'end', behavior: 'smooth'});
}
return (
<>
<...some other components>
<Button onClick={onClick}>Click me to be forwarded</Button>
<ChildComponent ref={childReference}/>
</>
);
};
ChildComponent.jsx
import React from 'react';
const ChildComponent = (props, ref) => {
const { name, value, description } = props;
return (
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
);
};
ChildComponent.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.number,
description: PropTypes.string,
};
ChildComponent.defaultProps = {
value: 0,
description: '',
};
export default React.forwardRef(ChildComponent);
我知道上面的代码不起作用,它只是为了说明我正在努力实现的目标。
我真的尝试了通过谷歌搜索找到的所有其他解决方案,它们看起来都很简单,但其中 none 似乎适用于我的用例。我也尝试过使用 forwardRef,但这对我来说也没有解决问题。
更新
我想我对什么不起作用有点含糊。我在实施过程中收到了很多不同的错误消息。
以下为其中之一:
Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
解决方案
好的。我想我会 assemble 这里的片段与@Vencovsky 提供的解决方案。
这是问题中看到的两个示例组件的完整实现:
ParentComponent.jsx
import React, { useRef } from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = props => {
const childReference = useRef(null);
const scrollIntoView = () => {
childReference.current.scrollIntoView({block: 'center', inline: 'center', behavior: 'smooth'});
}
return (
<>
<...some other component>
<Button onClick={scrollIntoView}>Click me to be forwarded</Button>
<ChildComponent ref={childReference}
</>
);
};
export default ParentComponent;
ChildComponent.jsx
import React, {forwardRef} from 'react';
import PropTypes from 'prop-types';
const ChildComponent = forwardRef((props, ref) => {
const { name, value, description } = props;
return(
<>
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
</>
);
});
ChildComponent.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.number,
description: PropTypes.string,
};
ChildComponent.defaultProps = {
value: 0,
description: '',
};
export default ChildComponent;
编辑 2:
我猜你在做类似的事情
const ChildComponent = (props, ref) => { ... }
ChildComponent.propTypes = { ... }
export default React.forwardRef(ChildComponent)
但是你需要做的是在 React.forwardRef
之后传递 propTypes
,像这样:
const ChildComponent = (props, ref) => { ... }
const ForwardComponent = React.forwardRef(ChildComponent)
ForwardComponent.propTypes = { ... }
export default ForwardComponent
更好的方法是
// using forwarRef
const ChildComponent = React.forwarRef((props, ref) => {
const { name, value, description } = props;
return (
<...some other components>
<Button ref={ref}>You should be forwarded to me</Button>
);
});
那么您就不需要更改 propTypes
并创建另一个组件。
编辑:
作为您的编辑,我看到您忘记使用 React.forwardRef
。
你应该添加
export default React.forwardRef(ChildComponent)
到您的 ChildComponent
文件(使用 forwardRef 导出)。
什么不起作用?你有错误吗?你应该更好地解释发生了什么,但我会尝试猜测。
有些东西会导致它无法正常工作。
- 您需要使用
ref.current.foo
而不是ref.foo
- 正如@JeroenWienk 所说:
It seems that your button is also a custom component. Are you sure the ref is being passed to the html button element inside there?
- 要使用功能组件的第二个参数,您应该使用
React.forwardRef
。例如export default React.forwardRef(ChildComponent)