【问题标题】:Populate input fields from axios response reactjs从 axios 响应 reactjs 填充输入字段
【发布时间】:2021-03-15 04:10:22
【问题描述】:

我有简单的字段。我想根据从 axios 响应中获得的数据填充输入框。见下图

我正在使用钩子将数据保存到状态。 我的问题是如何在单击获取详细信息按钮(来自 api 的响应)时填充输入框。

见下面的代码

const [data, setData] = useState([])
const [advisoryDetails, setadvisoryDetails] = useState({
    ADVISORYID: '',
    ADVISORYDESC: '',
    CREATEDBY:'',
    MODIFIEDBY:'',
    STATUS1: ''        
})
const [advisoryDetails1, setadvisoryDetails1] = useState([])
const [advisoryID, setadvisoryID] = useState('')

const getAdvisoryTest = async () => {
    await axios.post('/API',advisoryID)
    .then(response => {
        console.log(response.data)
        setData(response.data)
        console.log('data',data)
        setadvisoryDetails1(response.data)
        console.log('advisoryDetails1',advisoryDetails1)
        alert('success')
    })

advisoryDetails1.map(adv => {
        advisoryDetails.ADVISORYID = adv.ADVISORYID;
        advisoryDetails.ADVISORYDESC = adv.ADVISORYDESC;
        advisoryDetails.CREATEDBY = adv.CREATEDBY;
        advisoryDetails.MODIFIEDBY = adv.MODIFIEDBY;
        if(adv.CREATEDBY && adv.MODIFIEDBY != '')
        {
            advisoryDetails.STATUS1 = 'Modified'
        }
        else{ advisoryDetails.STATUS1 = 'New'}

        console.log('populate',advisoryDetails)
    })
}
const txtAdvIdOnChange = e =>{
    setadvisoryID(prevState =>({
        ...prevState,
        'ADVISORYID':e.target.value
    }));
    console.log('onChange ID:',advisoryID)
}
return(
    <div>
        <label>AdvisoryID: </label>
        <input type='text' placeholder='Advisory ID' className='txtAdvisoryID' onChange={txtAdvIdOnChange} />
<button onClick={()=>getAdvisoryTest()}>Get Details</button>
        <br /><br />
<label>Advisory Desc: </label>
        <input type='text' placeholder='textbox1' className='txtAdvisoryDesc' value={advisoryDetails&&advisoryDetails.ADVISORYDESC} disabled/>
        <br/>
        <label>New / Modified: </label>
        <input type='text' placeholder='textbox2' className='txtStatus' value={advisoryDetails&&advisoryDetails.STATUS1} disabled/>
</div>)

即使在 console.log 中,也没有填充这些代码输入框 希望你能帮我谢谢。

【问题讨论】:

  • 你为什么有advisoryDetails.STATUS1 = 'Modified'?使用setadvisoryDetails 更新状态,如下所示:setadvisoryDetails(prevState =&gt; ({...prevState, STATUS1: "Modified"}))
  • 而且您知道,由于您正在遍历数组advisoryDetails1,它只是将数据覆盖到advisoryDetails,您将看到最后一次迭代的值
  • @HaseebA 哦,是的,呵呵,我的错。但是我在点击获取详细信息按钮时仍然无法填充输入框
  • 如果您将response.data 设置为advisoryDetails1 为什么不使用响应的数据来更新它,因为它可能的advisoryDetails1 那时还没有更新。 ``` const respData = response.data; if (respData.length > 0) { const adv = respData[respData.length-1]; setadvisoryDe​​tails((prevState) => ({ ...prevState, ...adv, STATUS1: adv.CREATEDBY && adv.MODIFIEDBY != '' ? 'Modified' : 'New' })) } ```
  • 嗨@HaseebA,您可以发布您的答案以便我将其标记为正确答案吗?谢谢

标签: javascript reactjs


【解决方案1】:

我认为您可以像下面这样重构您的代码。 我已将 set setadvisoryDetails 移动到 .then() 的 axios 内,因为您使用的是相同的数据,如果您只想要最后一次迭代的值,则不必遍历循环。在输入中,您不必检查 advisoryDetails 是否存在或具有非空值,因为您已在 const [advisoryDetails, setadvisoryDetails] = useState({...}) 中对其进行了初始化

const App = (props) => {
  const [data, setData] = useState([])
  const [advisoryDetails, setadvisoryDetails] = useState({
    ADVISORYID: '',
    ADVISORYDESC: '',
    CREATEDBY: '',
    MODIFIEDBY: '',
    STATUS1: ''
  })
  const [advisoryDetails1, setadvisoryDetails1] = useState([])
  const [advisoryID, setadvisoryID] = useState('')

  const getAdvisoryTest = () => {
    axios.post('/API', advisoryID)
      .then(response => {
        const respData = response.data;
        setData(respData)
        setadvisoryDetails1(respData)

        console.log({
          respData, data, advisoryDetails1
        });

        alert('success');

        if (respData.length > 0) {
          const adv = respData[respData.length - 1];
          setadvisoryDetails((prevState) => ({
            ...prevState,
            ...adv,
            STATUS1: adv.CREATEDBY && adv.MODIFIEDBY != '' ? 'Modified' : 'New'
          }))
        }

      })
  }

  const txtAdvIdOnChange = e => {
    setadvisoryID(prevState => ({
      ...prevState,
      'ADVISORYID': e.target.value
    }));
    console.log('onChange ID:', advisoryID)
  }

  return (
    <div>
      <label>AdvisoryID: </label>
      <input type='text' placeholder='Advisory ID' className='txtAdvisoryID' onChange={txtAdvIdOnChange} />
      {/* If you're just passing a function without any param or event params, then just pass the function name like a variable */}
      <button onClick={getAdvisoryTest}>Get Details</button>
      <br /><br />
      <label>Advisory Desc: </label>
      <input type='text' placeholder='textbox1' className='txtAdvisoryDesc' value={advisoryDetails.ADVISORYDESC} disabled />
      <br />
      <label>New / Modified: </label>
      <input type='text' placeholder='textbox2' className='txtStatus' value={advisoryDetails.STATUS1} disabled />
    </div>
  );
}

【讨论】:

    【解决方案2】:

    当您单击获取详细信息按钮时,您的状态没有更新,这就是问题所在(值仅在状态更新时更改,否则不会更新)

    //before don't do like this 
    advisoryDetails1.map(adv => {
            advisoryDetails.ADVISORYID = adv.ADVISORYID;
            advisoryDetails.ADVISORYDESC = adv.ADVISORYDESC;
            advisoryDetails.CREATEDBY = adv.CREATEDBY;
            advisoryDetails.MODIFIEDBY = adv.MODIFIEDBY;
            if(adv.CREATEDBY && adv.MODIFIEDBY != '')
            {
                advisoryDetails.STATUS1 = 'Modified'
            }
            else{ advisoryDetails.STATUS1 = 'New'}
    
            console.log('populate',advisoryDetails)
        })
    
    
    
    
    
    //after(only last element of advisoryDetails1 array was updated in the state)
     advisoryDetails1.forEach(adv => {
        let STATUS1 ='New'
        if(adv.CREATEDBY && adv.MODIFIEDBY != '')
        {
            STATUS1  = 'Modified'
        }
       
         setadvisoryDetails({ADVISORYID : adv.ADVISORYID,
            ADVISORYDESC:adv.ADVISORYDESC,
            CREATEDBY:adv.CREATEDBY,
            MODIFIEDBY:adv.MODIFIEDBY,
           STATUS1:STATUS1 
         })
       })
    

    如果您想查看您的 AdvisoryDe​​tails1 数组中的最后一个元素,请这样做

     let adv=advisoryDetails1[advisoryDetails1.length -1];
        let STATUS1 ='New'
        if(adv.CREATEDBY && adv.MODIFIEDBY != '')
        {
            STATUS1  = 'Modified'
        }
       
         setadvisoryDetails({ADVISORYID : adv.ADVISORYID,
            ADVISORYDESC:adv.ADVISORYDESC,
            CREATEDBY:adv.CREATEDBY,
            MODIFIEDBY:adv.MODIFIEDBY,
            STATUS1:STATUS1 
         })
     
    
    
     //it update your advisoryDetails state when advisoryDetails1 changed
      useEffect(()=>{
        advisoryDetails1.forEach(adv => {
        let STATUS1 ='New'
        if(adv.CREATEDBY && adv.MODIFIEDBY != '')
        {
            STATUS1  = 'Modified'
        }
       
         setadvisoryDetails({ADVISORYID : adv.ADVISORYID,
            ADVISORYDESC:adv.ADVISORYDESC,
            CREATEDBY:adv.CREATEDBY,
            MODIFIEDBY:adv.MODIFIEDBY,
           STATUS1:STATUS1 
         })
       })
      },[advisoryDetails1]);
    //check whether advisoryDetails is changed or not 
          useEffect(()=>{
            console.log('populate',advisoryDetails)
          },[advisoryDetails])
    

    一切都很好,但不是这样,只有数组的最后一个元素被更新了,所以您必须根据您的要求进行一些更改

    【讨论】:

    • 嗨@baskaran-ajiharan,在使用您的第二组代码时,在//after comment下。在首次单击时,advisoryDe​​tails 尚未填充数据(我通过 console.log 检查了它)。我想在单击按钮后立即填充advisoryDe​​tails,以便我使用它并立即填充输入框。谢谢
    • 我确保 axios 响应只返回一组数据。
    • 我刚刚更新了我的答案,你可以重新检查一下吗&你不能直接用 console.log 语句检查,因为它是异步的。您只能使用渲染方法或 useEffect 挂钩进行检查。如果您的数据只有一组,则作为对象返回,不要在后端作为数组返回
    【解决方案3】:

    在您的输入值属性中,尝试在&amp;&amp; 的任一侧添加一个空格。

    <input type='text' placeholder='textbox2' className='txtStatus' value={advisoryDetails.STATUS1 && advisoryDetails.STATUS1} disabled/>
    

    【讨论】:

    • 仍然遇到同样的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    • 2017-06-03
    • 2021-11-10
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多