Reputation: 457
I am developing UI using react ,have two input field On UI, both are having some dynamic value coming from server as JSON data, I am looping the data and showing data on UI.
I have one button on click of which what I want to one of input field data whose id match.
So I am using useEffect
on button click and trying to override data but it is not showing new data on UI.
useEffect(() => {
let pData = [
{
fname: "test",
lname: "test1",
id: 1
}
];
test.map((li) => {
if (li.component_id === pData[0].component_id) {
return { ...li, fname: pData[0].fname };
}
});
}, [triggerdata]);
On click I am doing this
const btnClick = () => {
setTriggerData(!triggerdata);
};
Edit/Update
I am getting data from another component as props and setting it to state
let [copmData, setCompData] = useState(props.data);
And in my useEffect
I am doing this
useEffect(() => {
let pData = [
{
fname: "test",
lname: "test1",
id: 1
}
];
copmData = copmData.map((li) => {
if (li.id === pData[0].id) {
return { ...li, fname: pData[0].fname };
}
return li;
});
}, [triggerdata]);
Upvotes: 0
Views: 515
Reputation: 2135
Updated your sandbox - https://codesandbox.io/s/intelligent-wood-5th2p
There were multiple problems:
test
) inside of component - so it will actually always be resetted back to default, so i moved it outside.map
function you were checking property .component_id
, which you don't have in testData objects, you should have used .id
test.map
- returns new array, so you need to do test = test.map
map
function you were not returning the result if your if
statement is not firing - but you should, otherwise you will arrays of undefineddefaultValue
, you should have used value
instead. defaultValue
is not resetting after re-render (hence no update seen)key
property.Final code:
let test = [ //initializing test data OUTSIDE of component
{
fname: "Michel",
lname: "Clark",
id: 1
},
{
fname: "Steve",
lname: "Smith",
id: 2
}
];
export default function App() {
const [triggerdata, setTriggerData] = useState(true);
useEffect(() => {
let pData = [
{
fname: "test",
lname: "test1",
id: 1
}
];
test = test.map((li) => { //Here i'm setting test to result of mapping
if (li.id === pData[0].id) { //here you were using .component_id
return { ...li, fname: pData[0].fname };
}
return li; //here you were missing return
});
}, [triggerdata]);
const btnClick = () => {
setTriggerData(!triggerdata);
};
return (
<div className="App">
<button onClick={btnClick}>Click</button>
{test.map((li, index) => (
<div key={index}> //you didn't provide unique key
<input value={li.fname} /> //here you were using defaultValue
</div>
))}
</div>
);
}
UPDATE
So in your new code you had yet another multiple issues.
setCompData
useEffect
runs on initial render, so you your update logic is executed "right when" component is mounted, meaning you will have your "test" update immediately, not after you press the buuton, so you need some condition there, i suspect by your logic you would need if(triggerdata)
Sandbox - https://codesandbox.io/s/ecstatic-sanderson-nenrr
Updated part:
useEffect(() => {
if (triggerdata) { //you need if to run your logic only after user click the button
let pData = [
{
fname: "test",
lname: "test1",
id: 1
}
];
setCompData( //use the state setter, not compData = compData.map
copmData.map((li) => {
if (li.id === pData[0].id) {
return { ...li, fname: pData[0].fname };
}
return li;
})
);
} else {
setCompData(props.data);
}
}, [triggerdata]);
Upvotes: 4