简体   繁体   English

你可以从 React.js 中的 useEffect 传递钩子作为 prop 值吗?

[英]Can you pass hooks as a prop value from an useEffect in React.js?

I'm new to react and think I'm not understanding the concept of a useEffect.我是新手,我认为我不理解 useEffect 的概念。 I have an array of objects in a.js file called cardData.我在一个名为cardData 的.js 文件中有一个对象数组。 I use this data to automatically generate cards and each card generates a button with the id based on that data when mapped.我使用这些数据自动生成卡片,每张卡片在映射时根据该数据生成一个带有 id 的按钮。 In this component, I'm trying to open a modal that will compare the id from an onMouseOver event to the data from the array of objects and find the object with the same id, so that I only render the content based on which cards button is clicked.在这个组件中,我试图打开一个模式,它将来自 onMouseOver 事件的 id 与对象数组中的数据进行比较,并找到具有相同 id 的 object,以便我只根据哪些卡片按钮呈现内容被点击。

function Portfolio(){
     
    const [modalOpen, setModalOpen] = useState(false);
    const close = () => setModalOpen(false);
    const open = () =>  setModalOpen(true) ;
    
    
    const [letterClass, setLetterClass] = useState("text-animate");
    const [ mouseId, setMouseId ] = useState(1);
    // const modalData = useRef([]);
    const [modalData, setModalData] = useState([]);
    

    useEffect(() => {
        setTimeout(() => {
          return setLetterClass('text-animate-hover')
        }, 3000)
      }, [])

      function handleMouseOver(event) {
        setMouseId(event.target.id)
      }

      function handleData(data){
        setModalData(cardData.find(obj => obj.id === data))
      }

If I hardcode a number into the handleData prop, it works, but when I set the prop equal to my mouseId, it returns undefined.如果我将一个数字硬编码到 handleData 道具中,它可以工作,但是当我将道具设置为等于我的 mouseId 时,它返回未定义。 The error shows: Cannot read properties of undefined (reading 'title').错误显示:无法读取未定义的属性(读取“标题”)。

    useEffect(() => {
        handleData(mouseId)
    }, [mouseId])
    

    function handleClick() {
        if (!modalOpen) {
            open();
        } else if (modalOpen) {
            close();
            
        }
    }

    return (<>
    <div className="port-content">
        <div className="container portfolio-page">
            <div className="port-text-zone">
                <h1>
                <AnimatedLetters idx={15} letterClass={letterClass} strArray={["M","y"," ","p","o","r","t","f","o","l","i","o","."]}/>
                </h1>
                <p>Since I'm such a versatile junior, I've worked on many different types of projects. My projects include design, front-end development and back-end development.</p>
            </div> 
        </div>
        <GeneratedCards id={handleClick} mouse={handleMouseOver}/>
        
    </div>
    {modalOpen && <><Modal 
    modalOpen={modalOpen} 
    handleClose={close} 
    />
            <ModalContent
                 title={modalData.title}
                 content={modalData.description}
                 desc1={modalData.modalDescription1}
                 desc2={modalData.modalDescription2}
                 desc3={modalData.modalDescription3}
                 projectLink={modalData.title} 
            /></>
    }
        <Loader type="ball-grid-beat" />
    </>)
}

export default Portfolio;

I think I'm getting this error either due to a useEffect not being able to pass data over to functions through props, or my data is set after I handle the click and the modal will not be able to display the content, because the specific object is not set in the before the onClick.我认为我收到此错误是因为 useEffect 无法通过道具将数据传递给函数,或者我的数据是在我处理点击后设置的,并且模态将无法显示内容,因为具体object 未设置在 onClick 之前。 Here is the github link.这是 github 链接。 https://github.com/HenryFord1998/my-portfolio-site/tree/refactor-and-Update https://github.com/HenryFord1998/my-portfolio-site/tree/refactor-and-Update

the mistake is from here const [modalData, setModalData] = useState([]);错误来自这里const [modalData, setModalData] = useState([]); where u set initial value of modalData to empty array, instead const [modalData, setModalData] = useState({});您将 modalData 的初始值设置为空数组,而不是const [modalData, setModalData] = useState({}); so useEffect is run after the component is finish render, thats why your modal component get undefined, because it try to use value from modal data array like an object所以 useEffect 在组件完成渲染后运行,这就是为什么您的模态组件未定义的原因,因为它尝试使用模态数据数组中的值,例如 object

u need to guard it before modalData is ready, u can use like this你需要在modalData准备好之前保护它,你可以这样使用

{modalOpen &&  (
<>
<Modal 
    modalOpen={modalOpen} 
    handleClose={close} 
    />
     {modalData && (
<ModalContent
                 title={modalData.title}
                 content={modalData.description}
                 desc1={modalData.modalDescription1}
                 desc2={modalData.modalDescription2}
                 desc3={modalData.modalDescription3}
                 projectLink={modalData.title} 
            />
)}
    </>
)}

Issue问题

The main issue is that the id properties in the cardData array are numbers, but the mouseId state is updated to a string type by event.target.id .主要问题是cardData数组中的id属性是数字,但是mouseId state 通过event.target.id更新为字符串类型。

function handleMouseOver(event) {
  setMouseId(event.target.id); // <-- string type
}

When trying to find a matching cardData object a strict ( === ) check is used.当试图找到匹配的cardData object 时,会使用严格的 ( === ) 检查。

function handleData(data){
  setModalData(cardData.find(obj => obj.id === data)) // <-- type mismatch
}

Since the types don't match they can never be strictly equal.由于类型不匹配,它们永远不可能严格相等。 Array.prototype.find returns undefined if no match is found via the predicate function.如果通过谓词 function 未找到匹配项,则Array.prototype.find返回undefined

Solution解决方案

Use a type-safe comparison.使用类型安全的比较。 I suggest converting to string types.我建议转换为字符串类型。

function handleData(data){
  setModalData(cardData.find(obj => String(obj.id) === String(data)))
}

And in the case that a match still isn't found the modal should have a an additional guard on it.如果仍然没有找到匹配项,则模态应该有一个额外的保护。

{modalOpen && modalData && (
  <>
    <Modal 
      modalOpen={modalOpen} 
      handleClose={close} 
    />
    <ModalContent
      title={modalData.title}
      content={modalData.description}
      desc1={modalData.modalDescription1}
      desc2={modalData.modalDescription2}
      desc3={modalData.modalDescription3}
      projectLink={modalData.title} 
    />
  </>
)}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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