我决定使用refs
挂钩输入,实际上我创建了一个自定义挂钩来使用获取的数据,然后制作参考!
function useCreateRefFromProfileDataFromApi(profileDataFromApi) {
const [profileData, setProfileData] = useState([]);
const newArray = profileDataFromApi.map((data) => React.createRef())
useEffect(() => {
setProfileData(newArray)
}, [profileDataFromApi.length])
return profileData
}
const profileData = useCreateRefFromProfileDataFromApi(profileDataFromApi);
我在地图功能中使用:
<ul className="list-none">
{profileDataFromApi.map((data, index) => {
const { id, name, value } = data
return (
<li key={id} className="text-textColor" onClick={() => handleClick(index)}>{name}{' '}
<input
ref={profileData[index]}
type="text"
value={value}
className=" mt-1 mb-2 bg-transparent border-0 px-3 py-3 text-textColor rounded focus:outline-none focus:ring w-full"
onChange={(e) => {
handleChange(index, e.target.value)
}}
/>
</li>
)
})}
</ul>
但是我无法获取 onChange 函数来更新值。
onClick
预期的工作:
function handleClick(index) {
profileData[index].current.focus();
}
但不是onChange
:
function handleChange(index, value) {
profileData[index].current.value = value
}
那么如何让 handleChange 更新,即 DOM 和profileDataFromApi
????
这也是整个组件:
import React, { useEffect, useState, useRef } from 'react';
import { v4 as uuidv4 } from 'uuid';
import getProfile from '../../clientApi/GetProfile'
import { useUser } from '../../lib/hooks'
export default function ProfilePage({ }) {
const interestedActivitiesRef = useRef();
const { user } = useUser();
const [profileDataFromApi, setProfileDataFromApi] = useState([]);
const [interestedActivities, setInterestedActivities] = useState([])
const [profileLoaded, setProfileLoaded] = useState(true);
const [input, setInput] = useState('')
function useCreateRefFromProfileDataFromApi(profileDataFromApi) {
const [profileData, setProfileData] = useState([]);
const newArray = profileDataFromApi.map((data) => React.createRef())
useEffect(() => {
setProfileData(newArray)
}, [profileDataFromApi.length])
return profileData
}
const profileData = useCreateRefFromProfileDataFromApi(profileDataFromApi);
useEffect(async () => {
if (user !== undefined && profileLoaded) {
setProfileLoaded(false);
const fetchProfile = async () => {
const { data } = await getProfile();
const { email } = data[0]._user
const obj = data[0];
const { __v, _user, _id, ...profile } = obj;
profile.email = email;
for (const profileProp in profile) {
if (profileProp === 'interested-activities') {
setInterestedActivities(oldArray => [...oldArray, { id: uuidv4(), 'name': profileProp, 'value': profile[profileProp] }]);
} else {
setProfileDataFromApi(oldArray => [...oldArray, { id: uuidv4(), 'name': profileProp, 'value': profile[profileProp] }]);
}
}
}
fetchProfile()
}
return () => { setProfileLoaded(true) }
}, [])
function handleClick(index) {
profileData[index].current.focus();
}
function handleChange(index, value) {
profileData[index].current.value = input
}
function handleInterestedActivitiesRefClick(ind) {
interestedActivitiesRef.current[ind].focus();
}
return (<div className="px-4 gap-3 grid">
<div className="card-body card glass ">
<div className="avatar online flex flex-row justify-center">
<div className="rounded-full w-24 h-24">
<img src="http://daisyui.com/tailwind-css-component-profile-1@94w.png" />
</div>
</div>
<div className="divider glass h-px " />
<div className="px-4 mt-5">
<p className="text-sm text-textColor block mb-5">Click on text e.g. "Interested Activities" to upate values.</p>
</div>
<div className="px-4 ">
<ul className="list-none">
{profileDataFromApi.map((data, index) => {
const { id, name, value } = data
return (
<li key={id} className="text-textColor" onClick={() => handleClick(index)}>{name}{' '}
<input
ref={profileData[index]}
type="text"
value={value}
className=" mt-1 mb-2 bg-transparent border-0 px-3 py-3 text-textColor rounded focus:outline-none focus:ring w-full"
onChange={(e) => {
handleChange(index, e.target.value)
}}
/>
</li>
)
})}
</ul>
</div>
</div>
</div >)
}