[英]Error : Function components cannot have refs.?
I am trying to convert class component to functional component
.我正在尝试将
class component to functional component
。 but getting this error但收到此错误
Function components cannot have refs. Function 组件不能有参考。 Did you mean to use React.forwardRef()?
你的意思是使用 React.forwardRef() 吗?
working example with class component
class component
的工作示例
https://codesandbox.io/s/highlight-search-results-wqtlm?file=/src/components/Search/List.js https://codesandbox.io/s/highlight-search-results-wqtlm?file=/src/components/Search/List.js
Now I change the list
class component to function component现在我将
list
class 组件更改为 function 组件
https://codesandbox.io/s/funny-bird-dkfpi?file=/src/components/List.js https://codesandbox.io/s/funny-bird-dkfpi?file=/src/components/List.js
my code breaks and give me below error我的代码中断并给我以下错误
Function components cannot have refs. Function 组件不能有参考。 Did you mean to use React.forwardRef()?
你的意思是使用 React.forwardRef() 吗?
please suggest how to fix this error请建议如何解决此错误
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;
You have 2 errors actually.你实际上有2个错误。
The first one is here:第一个在这里:
ref={focused && this.userRef}
The second one is here:第二个在这里:
const prev = usePrevious({ focusedUser });
useEffect(() => {
if (focusedUser !== prev.focusedUser && scrollIntoView) {
ensureFocusedItemVisible();
}
}, [focusedUser]);
And here is the fix with explanation in comments:这是在评论中解释的修复:
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.