Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Functional Components (Hooks) - Editable options #1325

Closed
mbv401920150 opened this issue Nov 12, 2019 · 9 comments
Closed

Functional Components (Hooks) - Editable options #1325

mbv401920150 opened this issue Nov 12, 2019 · 9 comments
Labels
wontfix This will not be worked on

Comments

@mbv401920150
Copy link

mbv401920150 commented Nov 12, 2019

I'm checking the Editable option, but only has documentation related of React Components (Classes).
I need help to know how to apply the same feature with a Functional Component (Using Hooks)...

https://material-table.com/#/docs/features/editable

onRowUpdate: (newData, oldData) =>
	new Promise((resolve, reject) => {
	  setTimeout(() => {
		{
		  const data = this.state.data;
		  const index = data.indexOf(oldData);
		  data[index] = newData;
		  this.setState({ data }, () => resolve());
		}
		resolve()
	  }, 1000)
	}),

I cannot figure out how to update a state and execute the function resolve().
Does somebody have the same problem?

Find the code right here
https://codesandbox.io/s/materialtableui-b35v3

@mbv401920150
Copy link
Author

mbv401920150 commented Nov 13, 2019

I resolved the scenario with a some adjustments to my first code... but I still required your POV to know if this solution is the best approach:

https://codesandbox.io/s/materialtableui-cpxz6

...seems it's working now, basically, I created a state that has the data array, the resolve function of the promise, and a date (Just used as log):

const [gridData, setGridData] = useState({
  data: [
    { name: "Mehmet", surname: "Baran", birthYear: 1987, birthCity: 63 },
    { name: "Zerya Betül", surname: "Baran", birthYear: 2017, birthCity: 34 }
  ],
  resolve: () => {},
  updatedAt: new Date()
});

And to update and resolve the promise I use an effect:

useEffect(() => {
  gridData.resolve();
  console.log("RESOLVE AT:", gridData.updatedAt);
}, [gridData]);

The editable functions:

const onRowAdd = newData =>
  new Promise((resolve, reject) => {
    const { data } = gridData;
    const updatedAt = new Date();
    data.push(newData);
    setGridData({ ...gridData, data, resolve, updatedAt });
  });

const onRowDelete = oldData =>
  new Promise((resolve, reject) => {
    const { data } = gridData;
    const updatedAt = new Date();
    const index = data.indexOf(oldData);
    data.splice(index, 1);
    setGridData({ ...gridData, data, resolve, updatedAt });
  });

const onRowUpdate = (newData, oldData) =>
  new Promise((resolve, reject) => {
    const { data } = gridData;
    const updatedAt = new Date();
    const index = data.indexOf(oldData);
    data[index] = newData;
    setGridData({ ...gridData, data, resolve, updatedAt });
  });

I used a destruct to use the data array of the state into the Material Table:

const { data } = gridData;

return (
  <div className="App">
    <MaterialTable
      ...
      data={data}
      editable={{
        isEditable: rowData => true,
        isDeletable: rowData => true,
        onRowAdd: onRowAdd,
        onRowUpdate: onRowUpdate,
        onRowDelete: onRowDelete
      }}
    />
  </div>
);

...this approach is the best? Or have some flaws that I not see...

Thanks!

@karanness86
Copy link

i used the code above that @mbv401920150 provided as an example to solve my onRowUpdate issue. Thank you so much.

@DanielFerszt
Copy link

DanielFerszt commented Mar 30, 2020

Hi, I used the code you provided @mbv401920150 and it worked fine, but when I changed ir to receive data from props it stoped updating.
I edit a field, and data changes in the state and variables, but the table renders the old data.
I only changed this:

const [gridData, setGridData] = useState({
    data: props.data,
    resolve: () => {},
    updatedAt: new Date()
  });

Originally I had a callback to a parent component that handles the data request and logic. That callback changed the state in the parent, that was then passed as props to the table. But I removed all of that, trying simply to take data from props, and then updating the state within the table component.

I print the data variable to the console before rendering, and it contains the new values, except for a tableData element.

const { data } = gridData;
  console.log("State", data)
  return (
    <div>
    ...

console output:

State 
(3) [{…}, {…}, {…}]
0: {param: "Admin", val: "0"}
1: {param: "Margin", val: "0.4", tableData: {…}}
2: {param: "Price", val: "5080", tableData: {…}}
length: 3
__proto__: Array(0)

initial data printed to console:

State 
(3) [{…}, {…}, {…}]
0: {param: "Admin", val: "0.03", tableData: {…}}
1: {param: "Margin", val: "0.4", tableData: {…}}
2: {param: "Price", val: "5080", tableData: {…}}
length: 3
__proto__: Array(0)

Any Ideas?

@ScottEAdams
Copy link

@DanielFerszt - add a key to the table that is randomly set to force the refresh:

const [refreshKey, setRefreshKey] = useState(Math.random())

useEffect(() => {
  gridData.resolve();
  setRefreshKey(Math.random())
  console.log("RESOLVE AT:", gridData.updatedAt);
}, [gridData]);

<MaterialTable key={refreshKey}

@DanielFerszt
Copy link

Thanks, I'll try that. I solved the issue by adding a second state for the columns and refreshing that with every edit too... That forced the table to refresh.

@TroySchmidt
Copy link

I have also set the tableRef and called onQueryChange to force a refresh as well on row edits.

@lgm-dev
Copy link

lgm-dev commented Apr 8, 2020

Hey,

Can you please guys @TroySchmidt or @DanielFerszt provide a working exemple of your guys solution. I'm trying to move my project to react hooks and I'm not able to have my props containing the data of my table, passed down to that material-table.

I tried the refreshed keys already trick, but didn't make any difference.

    const [refreshKey, setRefreshKey] = useState(Math.random())
    const [gridData, setGridData] = useState({
  data: props.ingredients
  resolve: () => {}});

useEffect(() => {
  gridData.resolve();
  setRefreshKey(Math.random())

}, [gridData]);

@DanielFerszt
Copy link

Sure, here is a link to my question in stackOverflow where someone answered very well. He even explains a little more in the comments at my request.

https://stackoverflow.com/questions/60935643/react-material-table-editing-from-props-using-hooks/60957646?noredirect=1#comment107850018_60957646

Let me know it you need more help!

@stale
Copy link

stale bot commented Jul 8, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. You can reopen it if it required.

@stale stale bot added the wontfix This will not be worked on label Jul 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

7 participants