![](/img/trans.png)
[英]Error: Function components cannot have string refs. We recommend using useRef() instead
[英]Error : Function components cannot have refs.?
我正在尝试将class component to functional component
。 但收到此错误
Function 组件不能有参考。 你的意思是使用 React.forwardRef() 吗?
class component
的工作示例
https://codesandbox.io/s/highlight-search-results-wqtlm?file=/src/components/Search/List.js
现在我将list
class 组件更改为 function 组件
https://codesandbox.io/s/funny-bird-dkfpi?file=/src/components/List.js
我的代码中断并给我以下错误
Function 组件不能有参考。 你的意思是使用 React.forwardRef() 吗?
请建议如何解决此错误
import React, { useEffect, useRef, useState} from 'react';
import User from './User';
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
const List = ({users})=>{
const [focusedUser, setFocusedUser] = useState(-1);
const [scrollIntoView, setScrollIntoView] = useState(false);
const userRef = useRef();
const prev = usePrevious({focusedUser});
useEffect(()=>{
if (
focusedUser !== prev.focusedUser &&
scrollIntoView
) {
ensureFocusedItemVisible();
}
},[focusedUser])
const ensureFocusedItemVisible =()=> {
userRef.current &&
userRef.current.scrollIntoView({
behaviour: 'smooth',
block: 'center'
});
}
const handleKeyPress = e => {
// scroll into view only on keyboard navigation
setScrollIntoView( true );
// up arrow
if (e.keyCode === 38) {
const fu = focusedUser <= 0 ? 0 : focusedUser - 1;
setFocusedUser(fu);
}
// down arrow
if (e.keyCode === 40) {
const currentFocus = focusedUser;
// if down key is pressed multiple times on last list item, keep last item highlighted
const fu =
currentFocus >= users.length - 1
? users.length - 1
: currentFocus + 1;
setFocusedUser(fu);
}
};
const handleMouseEvent = id => {
userRef.current && userRef.current.focus();
setScrollIntoView(false);
setFocusedUser(parseInt(id))
};
const listElements = users.map((user, index) => {
const focused = index === focusedUser;
return (
<User
divId={index}
data={user}
focused={focused}
ref={focused && userRef}
handleKeyPress={handleKeyPress}
handleMouseEvent={handleMouseEvent}
/>
);
});
return <div className="result-list">{listElements}</div>;
}
export default List;
你实际上有2个错误。
第一个在这里:
ref={focused && this.userRef}
第二个在这里:
const prev = usePrevious({ focusedUser });
useEffect(() => {
if (focusedUser !== prev.focusedUser && scrollIntoView) {
ensureFocusedItemVisible();
}
}, [focusedUser]);
这是在评论中解释的修复:
import React, { useEffect, useRef, useState } from "react";
import User from "./User";
const List = ({ users }) => {
const [focusedUser, setFocusedUser] = useState(-1);
const [scrollIntoView, setScrollIntoView] = useState(false);
const userRef = useRef();
// You don't need to keep track of the previous value.
// useEffect will be called on first render and whenever one of the values in the dependencies array changes
// So it will run whenever the focusedUser changes
useEffect(() => {
if (scrollIntoView) {
ensureFocusedItemVisible();
}
}, [focusedUser, scrollIntoView]);
const ensureFocusedItemVisible = () => {
userRef.current &&
userRef.current.scrollIntoView({
behaviour: "smooth",
block: "center"
});
};
const handleKeyPress = e => {
// scroll into view only on keyboard navigation
setScrollIntoView(true);
// up arrow
if (e.keyCode === 38) {
const fu = focusedUser <= 0 ? 0 : focusedUser - 1;
setFocusedUser(fu);
}
// down arrow
if (e.keyCode === 40) {
const currentFocus = focusedUser;
// if down key is pressed multiple times on last list item, keep last item highlighted
const fu =
currentFocus >= users.length - 1 ? users.length - 1 : currentFocus + 1;
setFocusedUser(fu);
}
};
const handleMouseEvent = id => {
userRef.current && userRef.current.focus();
setScrollIntoView(false);
setFocusedUser(parseInt(id));
};
const listElements = users.map((user, index) => {
const focused = index === focusedUser;
return (
<User
key={index}
divId={index}
data={user}
focused={focused}
// if it isn't focused pass null
// the ref should be a function or a ref object or null
ref={focused ? userRef : null}
handleKeyPress={handleKeyPress}
handleMouseEvent={handleMouseEvent}
/>
);
});
return <div className="result-list">{listElements}</div>;
};
export default List;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.