0

我决定使用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 >)

}
4

1 回答 1

1

问题是您需要区分使用时处理输入更改的正确controlled-components方法是什么在每个 onChange 事件中更新它uncontrolled-componentsonChangecontrolled-componentinput.current.value

基本上这些是差异:

controlled-components:状态用于存储输入每次变化时的值,理想的情况是告诉输入它的值是状态值,这样值将是统一的并且始终相同。参考:https ://reactjs.org/docs/forms.html#control-components

uncontrolled-components:这个输入的值是通过绑定一个引用获得的,所以当你想访问这个值时你只需要做input.current.value Ref:https ://reactjs.org/docs/uncontrolled-components.html

于 2022-01-08T18:31:25.283 回答