React组件re-render异常:点击随机用户按钮后数据未同步更新
问题根因
你遇到的问题核心是ProfileCard组件没有监听传入的userData属性变化,新用户数据拉取完成后,组件内部的展示状态没有同步更新:
- 点击「随机用户」按钮时,你先修改
randomUserClicked状态触发内部useEffect重置状态,此时父组件的接口请求还未返回,重置用的仍是旧用户数据 - 等新的
userData传入子组件时,没有对应逻辑触发内部的title、value、flag状态更新,所以展示内容不会同步刷新
修复方案
1. 修改ProfileCard组件(核心修改)
移除不需要的randomUserClicked状态,直接监听userData变化来重置展示状态:
const ProfileCard = ({ userData, handleRandomUserClick }) => { const { image, name, email, dob, location, phone, password } = userData; // 删掉这行无用状态 // const [randomUserClicked, setrandomUserClicked] = React.useState(false); const defaultFlag = { name: 'active', email: '', dob: '', location: '', phone: '', password: '', }; const [flag, setFlag] = React.useState(defaultFlag); const [title, setTitle] = React.useState('My Name Is'); const [value, setValue] = React.useState(name); const handleValue = (e) => { if (e.target.dataset.label === 'name') { setTitle('My Name is'); setValue(name); setFlag(defaultFlag); } else if (e.target.dataset.label === 'email') { setTitle('My Email is'); setValue(email); setFlag({ name: '', email: 'active', dob: '', location: '', phone: '', password: '', }); } else if (e.target.dataset.label === 'dob') { setTitle('My Birthday is'); setValue(new Date(dob).toLocaleDateString()); setFlag({ name: '', email: '', dob: 'active', location: '', phone: '', password: '', }); } else if (e.target.dataset.label === 'location') { setTitle('I live in'); setValue(location); setFlag({ name: '', email: '', dob: '', location: 'active', phone: '', password: '', }); } else if (e.target.dataset.label === 'phone') { setTitle('My phone number is'); setValue(phone); setFlag({ name: '', email: '', dob: '', location: '', phone: 'active', password: '', }); } else if (e.target.dataset.label === 'password') { setTitle('My password'); setValue(password); setFlag({ name: '', email: '', dob: '', location: '', phone: '', password: 'active', }); } if (e.target.dataset.label === 'random') { handleRandomUserClick(); // 删掉这行无用代码 // setrandomUserClicked(!randomUserClicked); } }; // 修改useEffect依赖为userData,只要用户数据变化就重置展示状态 React.useEffect(() => { setTitle('My Name is'); setValue(name); setFlag(defaultFlag); }, [userData]); // 其余return代码保持不变 }
2. 可选优化:简化App组件逻辑
不需要额外的triggerFetch状态来触发接口请求,直接调用拉取方法即可:
function App() { const [userData, setUserData] = useState({}); const fetchUserData = async () => { const response = await fetch('https://randomuser.me/api/'); const data = await response.json(); setUserData(setFields(data.results[0])); }; const setFields = (userData) => { const fName = userData.name.first; const lName = userData.name.last; const fullName = fName + ' ' + lName; return { image: userData.picture.large, name: fullName, email: userData.email, dob: userData.dob.date, location: userData.location.street.name, phone: userData.phone, password: userData.login.password, }; }; useEffect(() => { fetchUserData(); }, []); const handleRandomUserClick = () => { fetchUserData(); }; // 其余return代码保持不变 }
内容的提问来源于stack exchange,提问作者emre-ozgun
相关产品推荐
相关产品推荐

