I have a provider that receives data prop, puts it in a state. Also, there are a few methods to manipulate that state.
I pass the state and the data prop to consumers, but every time I change the state, there is no difference between the prop and the state. I want to be able to see what changed so I could update that value.
import { createContext, useContext, useEffect, useState } from "react";
const TableContext = createContext({
data: [],
headings: [],
onChangeCellContent: () => {},
});
const TableProvider = ({ data, headings, children }) => {
const [tableData, setData] = useState(data);
const [tableHeadings, setHeadings] = useState(headings);
useEffect(() => {
setData((previousData) => {
return data.length !== previousData.length ? data : previousData;
});
}, [data]);
const onChangeHeadingCell = ({ key, value }) => {
setHeadings((oldHeadings) =>
oldHeadings.map((heading) => {
if (heading.key === key) {
heading.title = value;
}
return heading;
})
);
};
const onChangeCellContent = ({ rowId, cellKey, value }) => {
setData((previousData) =>
[...previousData].map((row) => {
if (row.id === rowId) {
row[cellKey] = value;
return row;
}
return row;
})
);
};
const onAddNewRow = (rowData) => {
setData((oldData) => [...oldData, rowData]);
};
return (
<TableContext.Provider
value={{
tableData,
data,
onChangeCellContent,
onChangeHeadingCell,
onAddNewRow,
headings: tableHeadings,
}}
>
{children}
</TableContext.Provider>
);
};
export default TableProvider;
export const useTable = () => {
const context = useContext(TableContext);
if (context === "undefined") {
throw Error("Table provider missing");
}
return context;
};
Here is the change handler, it works, but it also changes the original data:
const Row = ({ data: row}) => {
const { onChangeCellContent, headings, data } = useTable();
...
// GIVES ME THE SAME VALUE WHEN I TRIGGER ONCHANGE
console.log(row.value, data.find((s) => s.id === row.id).value);
return <tr><td><select
className="w-full h-full focus:outline-none"
style={{
backgroundColor: "inherit",
}}
value={row.value}
onChange={(e) =>
onChangeCellContent({
rowId: row.id,
cellKey: "value",
value: e.target.value,
})
}
>...</select></td></tr>