繁体   English   中英

错误:Function 组件不能有参考。?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM