0

I started my app without any state management dependencies and my app's state looked something like this:

 state = { ...initState, } ///some actions I need to perform handleChange = (e) => { this.setState(setDefaultValues(e)); this.setState(setBmr); this.setState(setTdee); this.setState(setTrainingAndRestDaysCal); this.setState(setTrainingMacros); this.setState(setRestMacros); } 

here I import my initState from separate file (to save some space). Then I have handleChange where I'm passing functions to multiple this.setState because my next state data depends on previous. I'm importing those functions from separate file (to save some space as well)

Then I came to the point where I realized I'm passing props all over the place so I introduced the new react's context API. Which works very well in my opinion. Kind of like a redux just without a big boilerplate. So this context API helped me with that prop drilling through the child components. To use the context API i had to do some changes to my state object, so it looks like this now:

 state = { ...initState, handleChange: (e) => { this.setState(setDefaultValues(e)); this.setState(setBmr); this.setState(setTdee); this.setState(setTrainingAndRestDaysCal); this.setState(setTrainingMacros); this.setState(setRestMacros); }, setTrainingTrueOrFalse: (isIt) => { this.setState({ trainingToday: !isIt }) }, saveNewMeal: (meal) => { const meals = this.state.meals this.setState({ meals: { ...meals, meal } }) } 

Here I added my handleChange to my state so I can pass it via context api. Then I have created some new functions on the state an realized my state now is getting too messy.

  1. I have a function on the state (handleChange ) that uses other functions imported from setStateFunctions.js
  2. I have functions where logic is not extracted to setStateFunctions.js

On a high level my app has 2 main components: Calculator & MealPlanner

  • Calculator - calculates the macros and calories and passes the result to MealPlanner
  • MealPlanner - uses data from calculator and creates meals

==================================================

  1. What's the better approach to structure my app's state and functions?
  2. Do I really need to introduce redux?
  3. What would be my reducers structure?
  4. How would this look like using just react's new context API?
2
  • Calling setState multiple times in one event is anti-pattern. If you are looking for something light weight, try MobX. It's easier than Redux, you don't have to restructure your existing code. Commented Mar 22, 2018 at 2:56
  • Thanks for your response. Will have a look to that. Commented Mar 22, 2018 at 3:11

1 Answer 1

1

Your app is sized right to go without adding redux for state management.

1) What's the better approach to structure my app's state and functions?

Let a top-level app maintain state that includes "handler" functions.

2) Do I really need to introduce redux?

Not needed. Keep your props organized and let the App handle the "events".

3) What would be my reducers structure?

Avoid it and go vanilla react.

4) How would this look like using just react's new context API?

Context feels overkill and possibly entangling (two components could drift on the understanding of how to use what is exposed as shared, global state in the context).

Let your composing App manage the state and pass props to the child components (Calculator and MealPlanner). You want two-way communication between those, so also pass "handling" functions that change the state within App to get the effect to ripple to the other via passed-in props. Something like the following:

class App extends React.Component { state = { ...initState, // not sure if this is global or what, but assuming defined handleCalculation: () => { // do some state changes on this ala this.setState() }, handlePlanning: () => { }, }; render() { return ( <div> <MealPlanner {...this.state} /> <Calculator {...this.state} /> </div> ); } } 

Let MealPlanner and Calculator set required propTypes accordingly.

Sign up to request clarification or add additional context in comments.

3 Comments

Appreciate your explanation. There are few things I'm concerned though. Isn't it an antipatern to pass entire state to multiple components? I.e like in your example you are passing entire state for both components even though they do not need entire state. I been reading about this but I don't know why it's antipatern to pass entire state all over the place. Does it influence performance? The app gets bigger? or what? What happens with the app when you pass entire state in multiple components? How does this compare to context api? For me it looks the same thing.
With context it is straight forward to get the state in to component without any props drilling, That's why I really like it
You're right in that passing {...this.state} hides the intent; was using it as a shortcut, but it is best to be explicit -- may accidentally pass what you intended to omit (i.e., some kind of behavior or rendering hint). As well, put the propTypes in place to require props from the containing component. I don't know about performance impact... object spread is cheap and the rendered js is simply passing a props object around.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.