Stateful components and state reset


#1

Hello everyone.
I’m a JS developer and I have used react on the past and more recently vue. In both cases, what I usually do is use a state management library (like vuex, redux, etc) and I just use stateless components.
This gives me the great advantage that on state change, the components state get literally reset.
With reason however, I’m following a different approach. Components are stateful and they encapsulate certain section of the aplication. Usually they get the starting information and manage the state while that information is valid.
The problem comes when I give them totally new information. The component does not get reset as I’m used to, they internal state stays the same, and I have to use some weird “reset” functions inside the willReceiveProps handler.
Is there a better way ? How can I force a full refresh of the component and it’s internal state?
Of course I can shift-up the state management and make them stateless components, but I’m scared of this getting crazy and hard to manage soon.
I remember when I tried to use react without redux, and I don’t want to live that experience never-ever again.

Here is an example of one of my simplest components


let make = (~session: Trainer.session, ~onComplete, _children) => {
  ...component,
  initialState: () => {
    let {session, current} = shift(session.exercises);
    {current, session, finished: false};
  },
  willReceiveProps: self => extendSlice(false, shift(session.exercises)), /* Reset the count on exercise update */
  reducer: (action, state: state) =>
    switch (action) {
    | Next => ReasonReact.Update(update(state))
    | Finish =>
      onComplete(session.name);
      ReasonReact.NoUpdate;
    },
  render: self =>
    !self.state.finished ?
      <RunExercise
        exercise={self.state.current}
        onComplete={_name => self.send(Next)}
      /> :
      <button onClick={_ => self.send(Finish)}>
        {ReasonReact.string("Finish session")}
      </button>,

I want to just reset it totally when a new session it’s provided to the component, but making it a stateful component is very convenient to “encapsulate” the life-cycle of a single session.

Thanks in advance


#2

willReceiveProps is the perfectly valid way of doing this as it returns freshly incoming props to state, so I believe you’re doing the right thing here!

If this at any point becomes too frickly you can always, as you said yourself, go a level higher to manage the state. But your example, at least for what I can derive from the use case, looks fine to me!


#3

Sorry, that I never answered you back. Thank you very much for confirming my guessings.

Regards


#4

I’ve got a lot of painful experience from using the willReceiveProps pattern to reset state. It very often leads to huge complexity months later when you try to add or change functionality. The react blog explains this much better than I could!


#5

Now that I have more experience with react I really think that the easiest way to reset state is doing it outside of the component. This simplifies the internals of the component because it only handles its scope and makes composition easier because you can reset from the outside however you want. How do that? By just using the key property. Not sure if this is possible on reason though