首页 > 解决方案 > 如何从反应钩子中的字符串动态执行useState?

问题描述

我有一个对象

const configs = [
  {
    label: 'Title',
    name: 'Title',
    value: titleToString,
    field: SinglelineTextfield,
    uniqueIdentifier: 0,
    stateVar: 'criticalObjectTitle',
    setStateVar: 'setCriticalObjectTitle',
  },
  {
      name: 'type',
      uniqueIdentifier: 1,
      label: 'type',
      value: typeToString,
      field: SinglelineTextfield,
      stateVar: 'criticalObjectType',
      setStateVar: 'setCriticalObjectType',
    },
    {
      name: 'Domain',
      label: 'Domain',
      value: domainToString,
      field: SinglelineTextfield,
      uniqueIdentifier: 2,
      stateVar: 'criticalObjectDomainName',
      setStateVar: 'setCriticalObjectDomainName',
    }
]

我正在检索 setState 变量 wwwith 我的 onChange 中的 setFindVal

 const onChange = async (e) => {
      

      const name = e.target.name || e.target.getAttribute('name')

      const value = e.target.innertext ? e.target.innertext
      : e.target.value

      const setFindVal = configs.find(config => config.name === name).setStateVar
      setFindVal(value)
      console.log(setFindVal(value));

    }

但是,当我想使用 setFindVal 作为 useState 钩子时,它告诉我 setFindVal 没有定义。当我记录 setFindVal 及其属性类型时,我得到它的字符串,所以我在我的函数之外创建了一个 useState 钩子,但是这仍然不起作用。如何将字符串转换为 useState 函数?

错误:

 Uncaught (in promise) TypeError: setFindVal is not a function

完整代码:

const editCriticalObjects = props => {

    const query = new URLSearchParams(props.location.search)
    const criticalObjectsId = query.get('id')

    const loading = useContext(LoadingContext)
    const user = useContext(UserContext)
    const testing = useContext(TestingFrameworkContext)

    const [editCriticalObjects, setEditCriticalObjects] = useState(null)

    const [findval, setFindVal] = useState(null)
  
    const [criticalObjectTitle, setCriticalObjectTitle] = useState(null)
    const [criticalObjectDomainName, setCriticalObjectDomainName] = useState(null)
  

    useEffect(() => {
      async function onLoadCriticalObjects() {
        loading.setLoading(true)
        const results = await get(`get_critical_objects?id=${criticalObjectsId}`, user.user)
        setEditCriticalObjects(results)
        loading.setLoading(false)
      }
      onLoadCriticalObjects()
    }, [])

    const assetIdObject = editCriticalObjects && editCriticalObjects.filter(obj => {
      if (obj.asset_id === criticalObjectsId )
      return obj
  })
  console.log(assetIdObject);

  const title = assetIdObject && assetIdObject.map(item => item.asset_id)
  console.log(titleToString);

 const titleToString = title && title.join(', ')

  const domain = assetIdObject && assetIdObject.map(item => item.Domains.toString())

  const domainToString = domain && domain.join(', ')

  const type = assetIdObject && assetIdObject.map(item => item.type.toString())

  const typeToString = type && type.join(', ')

     const configs = [
      {
        label: 'Title',
        name: 'Title',
        value: titleToString,
        field: SinglelineTextfield,
        uniqueIdentifier: 0,
        stateVar: 'criticalObjectTitle',
        setStateVar: 'setCriticalObjectTitle',
      },
      {
          name: 'type',
          uniqueIdentifier: 1,
          label: 'type',
          value: typeToString,
          field: SinglelineTextfield,
          stateVar: 'criticalObjectType',
          setStateVar: 'setCriticalObjectType',
        },
        {
          name: 'Domain',
          label: 'Domain',
          value: domainToString,
          field: SinglelineTextfield,
          uniqueIdentifier: 2,
          stateVar: 'criticalObjectDomainName',
          setStateVar: 'setCriticalObjectDomainName',
        }
    ]


    const getObjectParams = {
      asset_ids: criticalObjectTitle,
      asset: true,
      merge: true,
    }
 

    const onChange = async (e) => {
      

      const name = e.target.name || e.target.getAttribute('name')

      const value = e.target.innertext ? e.target.innertext
      : e.target.value

      const setFindVal = configs.find(config => config.name === name).setStateVar
      setFindVal(value)
      console.log(setFindVal(value));

    }

    const onClick = async () => {


      loading.setLoading(true)
      const results = await verifiedPost('post_critical_objects', testing.getObjectParams, user.user)
      loading.setLoading(false)


      console.log(getObjectParams);
    }

    return (!editCriticalObjects ? null :
    <React.Fragment>
      <PageWrapper title='Edit Critical Objects:'>
        <div className='Main Card editCriticalObjectFormWrapper'>
            {configs.map((config, k)=> {
                const Field = config.field
             return (
              <React.Fragment key={config.name} >
                <Field
                  style={{ marginBottom: '15px'}}
                  name={config.name}
                  placeholder={config.name}
                  value={config.stateVar}
                  initialValue={config.stateVar}
                  initialValues={config.stateVar}
                  uniqueIdentifier={k}
                  label={config.label}
                  onChange={onChange}
                />
              </React.Fragment>
             )
            })}

              <Button
                className='Button Ghost Approve'
                text='Submit'
                onClick={onClick}
              />
        </div>
      </PageWrapper>
    </React.Fragment>
    )
}

export default editCriticalObjects

记录一个值

新变化:

const onChange =  async (e) => {
  

  const name = e.target.name || e.target.getAttribute('name')

  const value = e.target.innertext ? e.target.innertext
  : e.target.value

  const setFindVal = configs.find(config => config.name === name).setStateVar;
  setStateValues[setFindVal](value);

  console.log(setFindVal, value);

}

标签: reactjs

解决方案


你得到它不是一个函数的原因是因为你只是使用来自 configs 对象的值,它是一个字符串。

您应该将该函数分配为 config 中的值

const configs = [
  {
    ...
    setStateVar: setCriticalObjectTitle,
  },
  {
     ...
     setStateVar: setCriticalObjectType,
  },
  {
     ...
     setStateVar: setCriticalObjectDomainName,
   }
];

推荐阅读