Reputation: 35
In my case I have a dropdown and based on the number selected with the dropdown some input fields appear. When I type into the input field the focus on that input field is lost after typing one character. Setting a unique key for each field is not solving my problem.
Link to the project: https://codesandbox.io/s/stoic-brahmagupta-m5014
const ItemPrice = () => {
const data = itemData.doReservation.eventPackage.item;
let emptyCat = {};
let emptyQnt = {};
let promoNum = {};
let emptyPromotion = {};
const [promoNumber, setPromoNumber] = useState(promoNum);
for (let it in data) {
let cat = {};
let promo = {};
for (let bt in data[it].buyertypes) {
cat[data[it].buyertypes[bt].id] = "";
emptyQnt[data[it].buyertypes[bt].id] = 0;
promo[data[it].buyertypes[bt].id] = "";
promoNum[data[it].buyertypes[bt].id] = [];
emptyPromotion[data[it].buyertypes[bt].id] = {};
}
emptyCat[data[it].id] = cat;
cat = {};
}
const [quantity, setQuantity] = useState(emptyQnt);
const [code, setCode] = useState(emptyPromotion);
const handleQuantity = (e) => {
const name = e.target.name;
const value = e.target.value;
setQuantity({
...quantity,
[name]: value
});
let num = [];
for (let i = 1; i <= value; i++) {
num.push(i);
}
setPromoNumber({ ...promoNumber, [name]: num });
let num2 = {};
for (let pn = 1; pn <= value; pn++) {
if (code[name]["code" + name + pn] === undefined) {
num2["code" + name + pn] = "";
} else {
num2["code" + name + pn] = code[name]["code" + name + pn];
}
}
setCode({ ...code, [name]: num2 });
};
const handleCode = (e) => {
e.preventDefault();
const sp = e.target.name.split(",");
const id1 = sp[0];
const id2 = sp[1];
const value = e.target.value;
setCode({
...code,
[id1]: {
...code[id1],
[id2]: value
}
});
};
const ShowData = () => {
let buyerTypes = [];
let items = [];
if (data) {
for (let it in data) {
items.push(
<div className="selectionHeader">
<div className="selHeadType">type</div>
<div className="selHeadQnt">Quantity</div>
<div className="selHeadCat">Price category</div>
</div>
);
for (let bt in data[it].buyertypes) {
buyerTypes.push({
dsc: data[it].buyertypes[bt].description,
qntId: data[it].buyertypes[bt].id
});
}
items.push(
<div>
{buyerTypes.map((i, index) => (
<div key={`a${index}`} className="selectionRowComp">
<div key={`c${index}`} className="selectionRow">
<h4 className="btDescription">{i.dsc}</h4>
<div className="NumberDropDown">
<select
value={quantity[i.qntId]}
onChange={handleQuantity}
name={i.qntId}
>
{[0, 1, 2, 3, 4, 5, 6].map((l) => {
return (
<option value={l} key={l}>
{l}
</option>
);
})}
</select>
</div>
</div>
<div>
{promoNumber[i.qntId].map((p, index) => (
<div key={`s${index}`}>
<label className="codeLabel">code {p}: </label>
<input
className="codeInput"
type="text"
value={code[i.qntId]["code" + i.qntId + (index + 1)]}
onChange={handleCode}
name={[i.qntId, "code" + i.qntId + (index + 1)]}
// required={hasPromotion[i.qntId]}
/>
</div>
))}
</div>
</div>
))}
</div>
);
buyerTypes = [];
}
}
return (
<div className="selectionItem">
{items.map((it, index) => {
return <div key={`w${index}`}> {it}</div>;
})}
</div>
);
};
const handleSubmit = (e) => {
e.preventDefault();
};
return (
<div>
<div>
<div>
<form onSubmit={handleSubmit}>
<ShowData />
</form>
</div>
</div>
</div>
);
};
Upvotes: 0
Views: 414
Reputation: 550
You have to decouple Parent (ItemPrice
) and Child (ShowData
) components respectively.
A through re-factor of your code is needed. Because dependencies like const data
is defined in ItemPrise
and used in child component ShowData
, rather it should be sent down as Props
to ShowData
component.
ShowData
component should not be directly dependent on any variable/const defined in ItemPrise
component. All such dependencies should be passed using any of the following basis your use-case and application requirements:
Props
Context
Redux
Upvotes: 2