useRef hook for more than 1 input elements

huangapple go评论73阅读模式
英文:

useRef hook for more than 1 input elements

问题

onClickNewGalley 函数中,您尝试在每个输入字段上使用 useRef 来获取它们的当前值,但只有 inputRef4 能正常工作。这可能是因为在 useEffect 中处理所有 inputRef 的焦点集中在最后一个 inputRef4 上。

要解决这个问题,您可以考虑在 onClickNewGalley 中使用一个循环来分别设置每个输入字段的焦点和状态。这里是一个可能的修改:

const onClickNewGalley = () => {
  setState({
    name: '',
    fullCarts: null,
    halfCarts: null,
    smu: null,
    stowage: null,
    firstClass: false,
    businessClass: false,
    premEconomy: false,
    economy: false,
  });

  // Toggle buttonClicked state
  setButtonClicked(!buttonClicked);

  // Focus on all input fields
  const inputRefs = [inputRef0, inputRef1, inputRef2, inputRef3, inputRef4];
  inputRefs.forEach((ref) => ref.current.focus());
};

这样,您可以确保所有输入字段都会获得焦点,并且它们的值都会被清空,而不仅仅是最后一个 inputRef4

英文:

i am using useRef hook in functional component to show input control when a button is clicked in react js.I have total 5 input fields which are individually defined.To meet my purpose of triggering input fields in all the 5 input elements i am assigning 5 useRef hooks to 5 constant variables and assigning the ref property to the corresponding input fields. my code is as follows,

import React, { useState ,useEffect,useRef} from 'react';
import '../../../assets/styles/modal.scss';
import closeIcon from '../../../images/icons/Icon2.png';
import deleteIcon from '../../../assets/icons/deleteRole.svg';
import { DFPAPIEndpoint, DFPAPIEndpointGalley } from "../../../utils/axios";
import { useTranslation } from 'react-i18next';
export const ConfigGalley = (props) => {
const { t } = useTranslation();
const [state,setState]=useState({name:'',fullCarts:null,halfCarts:null,smu:null,stowage:null,firstClass:false,businessClass:false,premEconomy:false,economy:false});
const [editState,setEditState]=useState({});
const [carts,setCarts]=useState([]);
const [selectedGalley,setSelectedGalley]=useState({});
const [buttonStatus,setButtonStatus]=useState(false);
const[modalFormStatusObj,setModalFormStatusObj]=useState({text:''})
const [inputFields,setInputFields]=useState(false);
const [buttonClicked,setButtonClicked]=useState(false);
const inputRef0=useRef(null);
const inputRef1=useRef(null);
const inputRef2=useRef(null);
const inputRef3=useRef(null);
const inputRef4=useRef(null);
const handleReset = () => {
let timerId = setTimeout(() => {
clearTimeout(timerId);
setState((_) => {
return { ..._, modalFormStatusObj: {text:''} };
})
}, 500)
setState({name:'',fullCarts:null,halfCarts:null,smu:null,stowage:null,firstClass:false,businessClass:false,premEconomy:false,economy:false})
checkEmptyFields(state);
}
useEffect(() => {
showUserRoles(props.airCraft?.galleys);
checkEmptyFields(state);
}, [props])
useEffect(() => {
if(buttonClicked){
inputRef0.current.focus();
inputRef1.current.focus();
inputRef2.current.focus();
inputRef3.current.focus();
inputRef4.current.focus();
}
}, [buttonClicked])
useEffect(() => {
if(!checkEmptyFields(state)){
setButtonStatus(false);
}
else{
setButtonStatus(true);
}
}, [state])
useEffect(() => {
if(props.airCraft){
setCarts(props.airCraft.galleys);
setInputFields(checkEmptyFields(state))
}
if(props.airCraft.galleys){
showUserRoles(props.airCraft.galleys);
}
}, [props.airCraft])
const checkEmptyFields=(state)=>{
for(let i in state) {
if(i==='name'||i==='halfCarts'||i==='fullCarts'||i==='smu'||i==='stowage'){
if (state['name'] !== '' && state["halfCarts"] && state["fullCarts"] && state["smu"] && state["stowage"])
return false;
}
}
return true;
}
const onChange = (e) => {
const { name, value } = e.target;
switch (name) {
case "name":
setState((_prev) => {
return { ..._prev, name:value };
});
break;
case "fullcarts":
setState((_prev) => {
return { ..._prev, fullCarts:value };
});
break;
case "halfcarts":
setState((_prev) => {
return { ..._prev, halfCarts:value };
});
break;
case "smu":
setState((_prev) => {
return { ..._prev, smu:value };
});
break;
case "stowage":
setState((_prev) => {
return { ..._prev, stowage:value };
});
break;
case "firstClass":
setState((_prev) => {
return { ..._prev, firstClass:true,businessClass:false,premEconomy:false,economy:false };
});
break;
case "businessClass":
setState((_prev) => {
return { ..._prev, firstClass:false,businessClass:true,premEconomy:false,economy:false };
});
break; case "premEconomy":
setState((_prev) => {
return { ..._prev,firstClass:false,businessClass:false,premEconomy:true,economy:false };
});
break; case "economy":
setState((_prev) => {
return { ..._prev, firstClass:false,businessClass:false,premEconomy:false,economy:true };
});
break;
default:
setState((_prev) => {
return { ..._prev,name:'',fullCarts:null,halfCarts:null,smu:null,stowage:null,firstClass:false,businessClass:false,economy:false,premEconomy:false };
});
break;
}
}
let isError = false,
updateStatusText="";
if (modalFormStatusObj) {
if (('text' in modalFormStatusObj)) {
updateStatusText= modalFormStatusObj.text;
}
}
const getClassCodeEdit=(ob)=>{
switch (ob?.classCode) {
case 'fc':
setState((_prev) => {
return { ..._prev,firstClass:!state.firstClass,businessClass:false,premEconomy:false,economy:false};
});
break;
case 'bcl':
setState((_prev) => {
return { ..._prev,firstClass:false,businessClass:!state.businessClass,premEconomy:false,economy:false};
});
break;
case 'pcy':
setState((_prev) => {
return { ..._prev,firstClass:false,businessClass:false,premEconomy:!state.premEconomy,economy:false};
});
break;
case 'ecy':
setState((_prev) => {
return { ..._prev,firstClass:false,businessClass:false,premEconomy:false,economy:!state.economy};
});
break;
default:
setState((_prev) => {
return { ..._prev};
});
break;
}
}
const onConfigClick=async(e,r)=>{
if(e.target.nodeName!=='IMG'&&e.target.nodeName!=='BUTTON'){
setSelectedGalley(r)
getClassCodeEdit(r)
setState((_prev) => {
return { ..._prev,name:r.name,fullCarts:r.carts[0].quantity,halfCarts:r.carts[1].quantity,smu:r.carts[2].quantity,stowage:r.carts[3].quantity};
});
setEditState((_prev) => {
return { ..._prev,id:r._id,name:r.name,fullCarts:r.carts[0].quantity,halfCarts:r.carts[1].quantity,smu:r.carts[2].quantity,stowage:r.carts[3].quantity};
})
setInputFields(false);
}
else{
setSelectedGalley(r)
if(r){
setButtonStatus(true)
try {
const resp = await DFPAPIEndpointGalley.delete(`galley/aircraftTypes/${props.airCraft.id}/galleys/${r._id}`);
if(resp.success){
setModalFormStatusObj({text:resp.message})
handleReset()
setButtonStatus(false)
props.setState((_) => {
return { ..._, resetDataSource: true };
})
}
} catch (error) {
setModalFormStatusObj({text: error.data.message})
handleReset()
}
}
}
}
const onEditSubmit=async()=>{
setButtonStatus(true);
const cartsObj=[
{
"id": "full",
"name": "Full Cart",
"weight": 0,
"volume": 0,
"dimensions": {
"length": 0,
"breadth": 0,
"height": 0
},
"quantity":  parseInt(state.fullCarts)
},
{
"id": "half",
"name": "Half Cart",
"weight": 0,
"volume": 0,
"dimensions": {
"length": 0,
"breadth": 0,
"height": 0
},
"quantity":  parseInt(state.halfCarts)
},
{
"id": "smu",
"name": "SMU",
"weight": 0,
"volume": 0,
"dimensions": {
"length": 0,
"breadth": 0,
"height": 0
},
"quantity": parseInt(state.smu)
},
{
"id": "stowage",
"name": "Misc. Stowage",
"weight": 0,
"volume": 0,
"dimensions": {
"length": 0,
"breadth": 0,
"height": 0
},
"quantity": parseInt(state.stowage)
}
]
let classCode;
switch (Object.keys(state).map((m,index)=> {if(state[m]===true){return m}}).filter(f=>f!==undefined)[0]) {
case 'firstClass':
classCode='fc'
break;
case 'businessClass':
classCode='bcl'
break;
case 'premEconomy':
classCode='pcy'
break;
case 'economy':
classCode='ecy'
break;
default:
classCode=""
break;
}
let temp= {
"name": state.name,
classCode,
carts: cartsObj
}
let body=[];
if(temp.name.length){
body.push(temp,...carts);
}
else{
body.push(...carts);
}
const updatedBody = body.map((item) => {
if (item.name === editState.name) {
return {
...item,
carts: cartsObj,
};
}
return item
})
let removeIndex = updatedBody.map(item => item.name).indexOf(selectedGalley.name);
removeIndex>=0 && updatedBody.splice(removeIndex, 1);
if(!checkEmptyFields(state)){
try {
const resp = await DFPAPIEndpointGalley.post(`galley/aircraftTypes/${props.airCraft.id}/galleys`,updatedBody[0]);
if(resp.success){
setModalFormStatusObj({text:resp.message})
setEditState({});
handleReset()
props.setState((_) => {
return { ..._, resetDataSource: true };
})
setButtonStatus(false);
}
} catch (error) {
setModalFormStatusObj({text: error})
handleReset()
}
}
}
const showUserRoles=(galleyArr)=>{
const result=galleyArr.map(gal=>{
return(<div className="form-group galley-modal"  id="one" onClick={(e)=>onConfigClick(e,gal)} style={{overflow:'auto'}}>
<ul className='list-group' style={{padding: "0 15px"}}>
<div className='role_card'>
<div style={{display:'inline-block'}}>
<p className='role_name'> {<h6 className="subheading-text-medium-title fontLight margLeft8">{gal.name}</h6>}</p>
{gal.carts.map((_,index) =>
<li className='list-group-item-role'style={{display:"inline"}} key={index} >
{<><button className='cart_display_galley'>
{_.name}<span className='galley_cart_count'>{_.quantity}</span>
</button>
</>}
</li>)}
<span className='remove_role_icon'>
<button style={{float:'right'}} id="two" className='mt-4 remove-button-galley' onClick ={(e)=>onConfigClick(e,gal)}>
<img className="icon-size-role" alt='deleteIcon' src={deleteIcon} />
</button>
</span>
</div>
</div>
</ul>
</div>)
}
)
return result
}
const onClickNewGalley=()=>{
setState((_prev) => {
return { ..._prev,name:'',fullCarts:null,halfCarts:null,smu:null,stowage:null,firstClass:false,businessClass:false,premEconomy:false,economy:false};
});
setInputFields(false);
setButtonClicked(!buttonClicked)
}
return (
<div className="overlay" role="dialog">
<div className="dialog sm-scrollbar">
<div className="dialog__content margBottom48">
<img className="modal__close_icon" alt='Close' src={closeIcon} onClick={props.onUploadClose} />
<h2 className="dialog__title subheading-text-medium fontMedium">{props.modelTitle}</h2>
<hr />
<button  style={{width:'1rem'}} id='newGalleyAdd' className="done-button subheading-text-medium-title fontLight" onClick={onClickNewGalley}>+ New Galley</button>
<div className="containe" style={{display:'flex',height:'400px'}}>
<div className='width50'>
<div className="">
<div>
{props.airCraft &&props.airCraft?.galleys&&showUserRoles(props.airCraft?.galleys)}
</div>
</div>
</div>
<div className='width10'></div>
<div className='width40'>
<div class=" dialog__container_item input-container">
<div class="dialog__description_config">
<label className='margBottom10'>Name *</label>
<input
id={''}
name="name"
placeholder='Name'
ref={inputRef0}
onChange={(e)=>onChange(e)}
disabled={inputFields}
value={state.name?state.name:''}
type={'text'}
className='edit-input'
/>
</div>
</div>
<div class="flexCol justifyContentSpaceEvenly ">
<div class=" dialog__container_item input-container">
<div class="dialog__description_config">
<label className='marginTop30' for='fullcarts' >Full Carts</label>
<input
id={'fullcarts'}
name='fullcarts'
placeholder='Full Carts'
ref={inputRef1}
onChange={(e)=>onChange(e)}
disabled={inputFields}
value={state.fullCarts?state.fullCarts:""}
type={'number'}
className='edit-input-galley'
/>
</div>
</div>
</div>
<div class="flexCol justifyContentSpaceEvenly ">
<div class=" dialog__container_item input-container">
<div class="dialog__description_config">
<label  className='marginTop30'>Half Carts</label>
<input
id={'halfcarts'}
name='halfcarts'
placeholder='Half Carts'
ref={inputRef2}
onChange={(e)=>onChange(e)}
disabled={inputFields}
value={state.halfCarts?state.halfCarts:""}
type={'number'}
className='edit-input-galley'
/>
</div>
</div>
</div>
<div class="flexCol justifyContentSpaceEvenly ">
<div class=" dialog__container_item input-container">
<div class="dialog__description_config">
<label className='marginTop30'>SMU</label>
<input
id="smu"
name='smu'
placeholder='SMU'
ref={inputRef3}
onChange={(e)=>onChange(e)}
disabled={inputFields}
value={state.smu?state.smu:''}
type={'number'}
className='edit-input-galley' />
</div>
</div>
</div>
<div class="flexCol justifyContentSpaceEvenly ">
<div class=" dialog__container_item input-container">
<div class="dialog__description_config">
<label className='marginTop30'>Misc. Stowage</label>
<input
id="stowage"
name='stowage'
placeholder='Stowage'
ref={inputRef4}
onChange={(e)=>onChange(e)}
disabled={inputFields}
value={state.stowage?state.stowage:''}
type={'number'}
className='edit-input-galley' />
</div>
</div>
</div>
<div style={{marginTop:'2.5rem'}} className='flexRow'>
<div class="flexCol justifyContentSpaceEvenly ">
<div class=" dialog__container_item input-container">
<div className='flexRow'>
<div className={`dialog__description__radio`}>
<label  class="control control-radio margRight30" for="1">
<input  id="1" type="radio"
name="firstClass"
value= {state.firstClass}
checked={state.firstClass}
disabled={inputFields}
onChange={onChange} />
<span>First Class</span>
<div class="control-indicator"></div>
</label>
</div>
</div>
</div>
</div>
<div class="flexCol justifyContentSpaceEvenly ">
<div class=" dialog__container_item input-container">
<div className='flexRow'>
<div className={`dialog__description__radio`}>
<label  class="control control-radio margRight30" for="2">
<input  id="2" type="radio"
name="businessClass"
value= {state.businessClass}
checked={state.businessClass}
disabled={inputFields}
onChange={onChange} />
<span>Business Class</span>
<div class="control-indicator"></div>
</label>
</div>
</div>
</div>
</div>
<div class="flexCol justifyContentSpaceEvenly ">
<div class=" dialog__container_item input-container">
<div className='flexRow'>
<div className={`dialog__description__radio`}>
<label  class="control control-radio margRight30" for="3">
<input  id="3" type="radio"
name="premEconomy"
value= {state.premEconomy}
checked={state.premEconomy}
disabled={inputFields}
onChange={onChange} />
<span>Premium Economy</span>
<div class="control-indicator"></div>
</label>
</div>
</div>
</div>
</div>
<div class="flexCol justifyContentSpaceEvenly ">
<div class=" dialog__container_item input-container">
<div className='flexRow'>
<div className={`dialog__description__radio`}>
<label  class="control control-radio margRight30" for="4">
<input  id="4" type="radio"
name="economy"
value= {state.economy}
checked={state.economy}
disabled={inputFields}
onChange={onChange} />
<span>Economy</span>
<div class="control-indicator"></div>
</label>
</div>
</div>
</div>
</div>
</div>
<div className='dialog_buttons margTop50 floatLeft flexRow'>
<button className="save-button" disabled={buttonStatus} onClick={onEditSubmit}>Save</button>
<button className="cancel-button-aircraft" onClick={onClickNewGalley}>Cancel</button>
</div>
<div className='margTop24'>
{Boolean(updateStatusText) ?
<>
<div className={ "dialog__statusBlock " + (isError ? 'alert_error' : 'alert_success') }>
{updateStatusText}
</div>
</> : null }
</div>
</div>
</div>
</div>
</div>
</div>
);
}
export const ConfigureGalley = (props) => {
const onUploadClose = (e) => {
removeContainerOverlay();
props.onUploadClose();
}
const removeContainerOverlay = () => {
/**
* Remove overlay to parent class
*/
(document.querySelectorAll('.content-container')[0]).classList.remove('modal-overlay-bg2');
};
return (
<ConfigGalley
modelTitle={props.modelTitle}
airCraft={props.airCraft}
setState={props.setState}
onUploadClose={onUploadClose}
/>
)
}

in the function onClickNewGalley() i am toggling the state of buttonClicked and using useEffect to get the current value of each input fields.But somehow only the inputRef4 is functioning in this implementation.what else could be done?

答案1

得分: 1

你只能一次只关注一个元素。

当选择一个文本字段并接受输入时,它被称为具有“焦点”。

英文:

You can only focus on one element at a time.

When a text field is selected and accepts input, it is said to have “focus.”

huangapple
  • 本文由 发表于 2023年6月12日 16:52:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76454980.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定