如何将子组件useEffect中的API返回值传递给父组件?
问题解决方案
错误原因
你遇到的toParentUser is not a function错误,核心原因是父组件SignUp在渲染子组件SignUpUserInput时,没有把定义好的toParentUser函数作为props传递给子组件,导致子组件接收的toParentUser是undefined,调用自然会报错。
修复步骤
1. 父组件传递toParentUser props
在父组件SignUp的SignUpUserInput标签中,添加toParentUser={toParentUser}属性,把函数传递给子组件:
// SignUp(父组件)修改后的return部分 return ( <SignUpWrap> <div className='signUpInputContent4'> {/* 新增toParentUser props传递 */} <SignUpUserInput userName={userName} setUserName={setUserName} toParentUser={toParentUser} /> </div> </SignUpWrap> )
2. 子组件添加边界判断(可选但推荐)
为了避免因props未传递导致的报错,可以在子组件调用toParentUser前先判断函数是否存在:
// SignUpUserInput(子组件)useEffect内修改 if (typeof toParentUser === 'function') { toParentUser(userData.data.isSuccess) }
3. 修复子组件其他未定义变量
你的子组件代码中还有两个未定义的变量:isUserName和onCheckName,这些也会导致报错,需要补充定义或者移除:
- 移除
InputWrap上的isUserName={isUserName}(如果不需要这个props),或者在子组件props中添加isUserName并从父组件传递 - 移除
onCheckName(e)调用(如果这个函数未定义),或者在子组件中定义该函数
完整修改后的代码
父组件SignUp
import React, { useState } from 'react' import styled from 'styled-components'; import SignUpUserInput from '../components/SingUp/SignUpUserInput'; const SignUpWrap = styled.div` flex-direction: column; display: flex; position: relative; z-index: 0; margin-bottom: calc(-100vh + 0px); ` function SignUp() { const toParentUser = (x) => { console.log('well done', x) } const [userName, setUserName] = useState(""); return ( <SignUpWrap> <div className='signUpInputContent4'> {/* 传递toParentUser函数 */} <SignUpUserInput userName={userName} setUserName={setUserName} toParentUser={toParentUser} /> </div> </SignUpWrap> ) } export default SignUp;
子组件SignUpUserInput
import React, { useEffect, useState } from 'react' import styled from 'styled-components'; import redX from '../../resources/images/img/redX.png' import axios from 'axios'; const InputWrap = styled.div` align-items: center; -webkit-appearance: none; background: rgb(250, 250, 250); border: 1px solid rgb(219, 219, 219); border-radius: 3px; ` function SignUpUserInput({userName, setUserName, toParentUser}) { useEffect (()=> { async function fetchData () { try{ const userData = await axios({ method : 'get', url : `https://cors-anywher.herokuapp.com/https://clone-instagram.shop:8080/users/checkid?id=${userName}` }); // 添加函数存在性判断 if (typeof toParentUser === 'function') { toParentUser(userData.data.isSuccess) } console.log(userData.data.isSuccess); } catch(error) { alert(error); } } // 避免空用户名时调用API if (userName.trim()) { fetchData(); } },[userName, toParentUser]) // 添加toParentUser到依赖数组 return ( <InputWrap> <label className='inputLabel'> <span className='inputHover'> 사용자 이름 </span> <input className='inputInput' value={userName} onChange={(e)=>{ setUserName(e.target.value); }}/> </label> </InputWrap> ) } export default SignUpUserInput;
额外提示
- 注意
cors-anywhere.herokuapp.com公共服务已停止免费使用,建议后端配置CORS,或者使用本地代理解决跨域问题 - 在
useEffect的依赖数组中添加toParentUser,避免React钩子依赖警告 - 可以在子组件调用API前判断
userName是否为空,避免不必要的请求
内容的提问来源于stack exchange,提问作者MontaKr
相关产品推荐
相关产品推荐

