下面的代码可以工作,但是如果this.buttonRef.current.firstChild.focus()
不在setTimeout函数中,则它会停止工作。
从参考的官方文档中我看不到为什么发生这种情况。我的组件明显有问题吗?如果不是,我想知道我的网站上是否有其他组件在“窃取”焦点,就像url
道具更改模式时那样。
更新:一件奇怪的事情是,如果我console.log
在setTimeout之外,那么我可以看到DOM中存在该元素。
UPDATE2:原来是导致该问题的原因是我的模式中的React Trap Focus。移除聚焦陷阱意味着我不需要超时。因为我需要焦点陷阱,所以我认为setTimeout将需要保留。
https://github.com/davidtheclark/focus-trap-react
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.buttonRef = React.createRef();
}
componentDidUpdate(prevProps) {
if (this.props.url === '' && prevProps.url = "old-url") {
console.log('target element: ', this.buttonRef.current.firstChild)
// This doenst work if not in a setTimeout
// this.buttonRef.current.firstChild.focus();
setTimeout(() => {
this.buttonRef.current.firstChild.focus();
}, 1);
}
}
render() {
const {
limitIsReached,
add
} = this.props;
return (
<Fragment>
<Title>My title</Title>
<Section>
<Button>
Add a promo code
</Button>
<span ref={this.buttonRef}>
{limitIsReached ? (
<Alert
message="Sorry limit reached"
/>
) : (
<Button
onClick={add}
>
Add new
</Button>
)}
</span>
<List compact />
</Section>
</Fragment>
);
}
}
export default MyComponent;
答案 0 :(得分:0)
考虑到componentDidUpdate似乎在解析buttonRef之前就已运行,所以短的setTimeout并不是最糟糕的解决方案。
您可以尝试其他涉及设置状态的方法:
componentDidUpdate(prevProps) {
if (.... oldurl) {
this.setState({focusBtn: true})
}
然后当buttonref解析时:
<span ref={ref=>{
if (this.state.focusBtn) {
this.buttonRef = ref;
this.buttonRef.current.firstChild.focus();
} } >...
编辑
好的,因此,如果您在渲染方法中删除条件,React将确保您的引用已在componentDidMount和componentDidUpdate上得到解析(如您所愿)
尝试一下:
<span ref={this.buttonRef}>
<Alert
message="Sorry limit reached"
style={{display: limitIsReached ? 'block' : 'none'}}
/>
<Button
onClick={add} style={{display: limitIsReached ? 'none' : 'inline-block'}}
>
Add new
</Button>
)}
</span>