0

I'm trying to render a stateful component inside react-window rows (using FixedSizeList), but their state (useState) is not maintained when they get re-rendered so it resets every time I scroll back to them. This makes sense because they're getting unmounted, but is there a way prevent re-rendering via memo or useCallback? I've seen some examples of avoiding re-renders, but I can't get them working. In this example sandbox I've made, I tried memoizing a component (<InnerRow>) that only takes a single prop, but it seems to keep re-rending it regardless of calling memo.

Am I not memoizing correctly or doing something wrong? Or is this not possible, and my only solution is to maintain the state in some other way, outside of the row component.

Zip184
  • 1,792
  • 2
  • 21
  • 34

2 Answers2

0

You can try by using useReducer instead of memo. Reducer will help you maintain state of clicked components even if they are not mounted in dom.

function reducer(state, action) {
  switch (action.type) {
    case "add": {
      return {
        isOn: [...state.isOn, action.payload]
      };
    }
    case "remove": {
      const newArray = [...state.isOn];
      const newState = newArray.filter((a) => a !== action.payload);
      return {
        isOn: newState
      };
    }
    default:
      throw new Error();
  }
}

You can check my solution here: https://codesandbox.io/s/keen-mclaren-nenc9v?file=/src/App.js

Lazar Nikolic
  • 4,261
  • 1
  • 22
  • 46
0

After some more research, I think that the answer to my question is: No Not possible. Where exactly would that memory live if it's no longer mounted? I'll have to keep the state elsewhere, like in the parent component, or via global state.

Zip184
  • 1,792
  • 2
  • 21
  • 34