Access outside parameter in SetState function - reactjs

I am not able to access onClick parameter inside setState function.
const [tableData, settableData] = useState({ tableDataList: [] });
const deleteRow = (rowId) => {
settableData(tData => {
//I have to access rowId to delete row with rowid from tData here
return tData;
});
}
.
.
//This button is inside a table. Present in all rows
<button className="btn-dark" onClick={() => deleteRow(rowId)}>DELETE</button>
Can any one help me to access rowId inside setState function?

You have to filter out using normal array methods from JavaScript. One example is the filter method that helps you filter the array based on how you like it to be filtered.
The following example will filter the array, returning all items, except for the item that matches the rowId, returning a new array without the deleted item:
tableData.tableDataList.filter(item => item.id !== rowId)
The full example must look something like this:
settableData(tData => {
return tData.tableDataList.filter(item => item.id !== rowId);
});

Related

Only rerender and fetch when api property has changed

Im trying to get the use effect to rerender only when the labels property has changed.
i want to fetch newest changes in the labels property only when there is a change.
My code below:
const usePrevious = (value: any) => {
const ref = useRef()
useEffect(() => {
ref.current = value
}, value)
return ref.current
}
const prevLabels = usePrevious(labels)
useEffect(() => {
if (labels !== prevLabels) {
fetchUpdatedLabels()
}
}, [labels, prevLabels])
const fetchUpdatedLabels = async () => {
await axios
.get(`/events/${printEvent.id}`)
.then((response) => {
const newLabels = response.data.labels
// filter response to empty array if there are no splits left
// if is null return empty string
let fetchedLabels =
newLabels !== null
? newLabels
.toString()
.split(',')
.filter((label: string) => {
return label !== ''
}) || ''
: ''
getLabels(fetchedLabels)
print.updateEvent(printEvent.id, 'value', printEvent.value)
})
.catch((err) => {
console.error(err, 'cant fetch labels from api')
})
}
it keeps refetching nonstop, how do i achieve this?
This is most likely in part because you are comparing an array with an array using the equivalence operator !==. It can be surprising to people new to JS but if you do this in a JS console:
[1,2,3] === [1,2,3]
It returns false. The reason is that an array is an object and what you are asking is "is the array on the left literally the same as the one on the right" -- as in the same variable. Whereas these are 2 separate array instances that happen to have the same contents. You might wonder why it works then on strings and numbers etc, but that's because those are primitive values and not objects which are instantiated. It's a weird JS gotcha.
There are several ways to compare an array. Try this:
useEffect(() => {
if (labels.sort().join(',') !== prevLabels.sort().join(',')) {
fetchUpdatedLabels()
}
}, [labels, prevLabels])
I'm not sure about your use case here though as when the labels are different, you fetch them, but the only way they can change is to be fetched? Is there something else in the code that changes the labels? If so, won't they get wiped out by the ones from the server now as soon as they change?
Something else is wrong here I think. Where do you set labels into state?

How to map the selected data in reactjs

I can get the data from what i selected
const onHandleSelectLocation = async (value) => {
console.log(value)
}
this is the data result from console.log
I am having a hard time getting the Email only, how can i achieve that? i've tried the value.email but it getting undefined.
The value shown in the log is array of objects, if you want to get the email, do the map instead
const onHandleSelectLocation = async (value) => {
console.log(value);
const emails = value.map(({ email }) => email);
console.log(emails);
}
value is an array with two objects, that includes email, id and name. if you want to access one of those, you can use map. you can mapping in array and use what properties that you need from objects.
for example like this:
value.map => ( item => <div key={item.id}> {item.email} </div>)

how to filter a componet by id in react js

I am learn reactjs and hand one project,but I could not completely fiddle some branch of the whole.I post the code below:
in the App.js:import React, { useState } from "react";
import colorData from "./color-data.json";
import ColorList from "./ColorList.js";
export default function App() {
const [colors, setColors] = useState(colorData);
const removeColor = id => {
const newColors = colors.filter(color => color.id !== id);
setColors(newColors);
};
const rateColor = (id, rating) => {
const newColors = colors.map(color =>
color.id === id ? { ...color, rating } : color
);
setColors(newColors);
};
return (
<ColorList
colors={colors}
onRemoveColor={removeColor}
onRateColor={rateColor}
/>
);
}
what is the "color => color.id !== id" used for?are they not the same: "color.id" and "id"
it is the project link:https://codesandbox.io/s/learning-react-color-organizer-2-forked-ke1gz?file=/src/App.js
color => color.id !== id is a predicate that's used to remove the color of the id that is passed to your removeColor function.
How this works is the filter function will iterate through each item of the array (colors in this example) and pass that item to a function you provide to check if it should be removed from the list. If the function is true, it's removed.
color => color.id !== id is the function that's called for each item, so if the current color's id equals the id that is passed to the removeColor function, then it's removed.
One thing to note is the original array isn't changed, it just returns a new array (newColors) with the items removed.
// function that takes an id as a parameter
const removeColor = id => {
// remove the color of the id that is passed by using the filter function
const newColors = colors.filter(color => color.id !== id);
// update your state with filtered colors
setColors(newColors);
};
The function removeColor takes in the parameter of id which is the id of the color to remove Using the Array.filters function.
The way filters works is it iterates through the array and whatever property fulfills the boolean condition in this case color.id !== id where color is an arbitrary element within the array and id is what is passed in as a parameter to the removeColor function.
More info on how Array.filter works here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Trying to generate a unique id for every item in my array

Im trying to pass in a unique id for every item that is added to cart. currently I have it working to adjust quantity and based on that the correct numbers of items are added to the cart. But lets say I have two of one item. Those two items are given the same id. Is there anyway to give them a unique id? Mainly for removing purposes.
current adding to cart function
const updateCart = () => {
itemToSend.forEach(element => {
addToCart(element);
});
};
you can use index of foreach function :
const updateCart = () => {
itemToSend.forEach((element, index) => {
addToCart(element, index);
});
};
and as better solution use .map method of es6 :
const updateCart = () => {
itemToSend.map((element, index) => {
addToCart(element, index);
});
};
and then use this unique index as id like below with combination of string:
<p id= {"element" + id }></p>
with this approach there is no need to add new library to your project
You can use uuid library to generate unique id

React Data Grid, how can I remove a row?

I using the example provided by React, and I want to have a button on every row and when it is clicked a row to be deleted.
https://codesandbox.io/s/5vy2q8owj4?from-embed
I am new to reactjs, it is possible to do it?
What I thought to do is to add another row with a button and inside the component to have a function like this, I don't know how to call this function from the outside:
{ key: "", name: "", formatter: () => <button onClick={() =>
this.deleteRows(title)}>Delete</button>}
deleteRows = (id) => {
let rows = this.state.rows.slice()
rows = rows.filter(row => row.id !== id)
this.setState({ rows })
}
Thanks
It's possible. You may use getCellActions to achieve this. Here's a working example: https://codesandbox.io/s/5091lpolzk

Resources