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

[EuiInMemoryTable] getDerivedStateFromProps can incorrectly block updates #3478

Closed
thompsongl opened this issue May 13, 2020 · 5 comments · Fixed by #3579
Closed

[EuiInMemoryTable] getDerivedStateFromProps can incorrectly block updates #3478

thompsongl opened this issue May 13, 2020 · 5 comments · Fixed by #3579
Labels

Comments

@thompsongl
Copy link
Contributor

The getDerivedStateFromProps method is set up with a false prioritization of updates. For instance, if both the items reference and the search reference change, only the items update propagates to new component state simply because the update logic occurs first.

static getDerivedStateFromProps<T>(
nextProps: EuiInMemoryTableProps<T>,
prevState: State<T>
) {
if (nextProps.items !== prevState.prevProps.items) {
// We have new items because an external search has completed, so reset pagination state.
return {
prevProps: {
...prevState.prevProps,
items: nextProps.items,
},
pageIndex: 0,
};
}
const { sortName, sortDirection } = getInitialSorting(
nextProps.columns,
nextProps.sorting
);
if (
sortName !== prevState.prevProps.sortName ||
sortDirection !== prevState.prevProps.sortDirection
) {
return {
sortName,
sortDirection,
};
}
const nextQuery = nextProps.search
? (nextProps.search as EuiSearchBarProps).query
: '';
const prevQuery = prevState.prevProps.search
? (prevState.prevProps.search as EuiSearchBarProps).query
: '';
if (nextQuery !== prevQuery) {
return {
prevProps: {
...prevState.prevProps,
search: nextProps.search,
},
query: getQueryFromSearch(nextProps.search, false),
};
}
return null;
}

Ideal case is to convert EuiInMemoryTable to a functional component and take advantage of hooks. Simpler case is to not return until each update logic check has finished.

@shrey
Copy link
Contributor

shrey commented Jun 7, 2020

@thompsongl I'd like to work on this issue.

@shrey
Copy link
Contributor

shrey commented Jun 7, 2020

          static getDerivedStateFromProps<T>(
           nextProps: EuiInMemoryTableProps<T>,
           prevState: State<T>
         ) {
           let updatedPrevState = prevState;
           if (nextProps.items !== prevState.prevProps.items) {
             // We have new items because an external search has completed, so reset pagination state.
             updatedPrevState = {
               ...updatedPrevState,
               prevProps: {
                 ...prevState.prevProps,
                 items: nextProps.items,
               },
               pageIndex: 0,
             };
           }
           const { sortName, sortDirection } = getInitialSorting(
             nextProps.columns,
             nextProps.sorting
           );
           if (
             sortName !== prevState.prevProps.sortName ||
             sortDirection !== prevState.prevProps.sortDirection
           ) {
             return {
               sortName,
               sortDirection,
             };
           }

           const nextQuery = nextProps.search
             ? (nextProps.search as EuiSearchBarProps).query
             : '';
           const prevQuery = prevState.prevProps.search
             ? (prevState.prevProps.search as EuiSearchBarProps).query
             : '';

           if (nextQuery !== prevQuery) {
             updatedPrevState = {
               ...updatedPrevState,
               prevProps: {
                 ...prevState.prevProps,
                 search: nextProps.search,
               },
               query: getQueryFromSearch(nextProps.search, false),
             };
           }
           if (updatedPrevState !== prevState) {
             return updatedPrevState;
           }
           return null;
         }

@thompsongl @chandlerprall Will this work?

@chandlerprall
Copy link
Contributor

That middle block, returning an object with only sortName and sortDirection, should also be changed to update the updatedPrevState value. Otherwise, the changes look right enough to test :)

@thompsongl
Copy link
Contributor Author

Otherwise, the changes look right enough to test :)

Yep, if you'd like to open a PR we can continue to work in there

@shrey
Copy link
Contributor

shrey commented Jun 8, 2020

Okay on it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants