Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining React local state with Redux global state

I'm making a web app where the user draws bounding boxes around objects in an image.

  • How I'm using React's local state: I store the properties of the rectangle while the user is still drawing (i.e. during mouseMove before mouseUp).
  • How I'm using Redux's global store: Once mouseUp fires, the drawing finishes, and updates to the rectangle are no longer made. I want to 'commit' this rectangle to Redux.

Is this the right and/or canonical way to handle state management?

I also want to pass both the React and Redux states (i.e. both the rectangle being drawn right now as well as the rectangles that have been 'committed' already in Redux) as props to a child React component.

Is this possible with react-redux's mapStateToProps? I can't seem to find a way to combine React state and Redux state together in mapStateToProps.

like image 669
jhuang Avatar asked Nov 18 '17 15:11

jhuang


People also ask

Can you use local state with Redux?

Using local component state is fine. Some common rules of thumb for determining what kind of data should be put into Redux: Do other parts of the application care about this data? Do you need to be able to create further derived data based on this original data?

Can you use Redux and useState together?

It is totally fine to use a mix of React component state and Redux state. You might for example use non-critical UI state inside React components, like if a checkbox is checked or not. The official Redux FAQ has a good list of rules of thumb for determining what kind of data should put into Redux.

Can I use Redux and state in functional component?

React Redux in functional components. The useAppSelector is used to read a value from the store state, and it also subscribes to the state's updates. The useDispatch Hook is used to dispatch actions to the reducer functions.


2 Answers

Just to elaborate a little more on AranS's answer and give you a direct correlation to your use case:

  1. The way you're doing it is fine in principle. You're keeping the very frequent state updates local (basically, mousemove while mousedown). It would be annoying and potentially inefficient to update the Redux state for every mouse move (ex: if using Redux logger, you'd needlessly get a mile-long log). You would only do so (as hinted at by AranS) if other components need to know the state of your mouse position in real time. I am using the same approach you are in a 3D modeling app and it works great.
  2. To save the shape's data in Redux, you would use standard Redux methodology. If you need to brush up, I would highly recommend googling for Redux' creator, Dan Abramov, as has published some useful and often free material (look at this series for example). mapStateToProps is typically used with mapDispatchToProps via react-redux's connect method. Giving you something like:

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)

like image 143
davidchappy Avatar answered Oct 20 '22 00:10

davidchappy


mapStateToProps is used to connect redux state with a component's props. You are basically doing two separate things:

  1. pass drawing details to the child component using the parent state:

    //Parent component render function
    render() {
        <ChildComponent rectangle={this.state.rectangle}/>
    }
    
  2. pass the redux state using mapStateToProps

Have you considered saving the drawing state in redux instead of the parent component state? This way, multiple components (such as the child component) are aware of the rectangle drawing.

P.S - you can use mapStateToProps for both react and redux state but this is redundant as you have already passed react props explicitly.

mapStateToProps = (state, ownProps) => {
   fromReduxStore: state.whatever,
   fromReactState: ownProps //doesn't make sense as this prop exists already on the child component  
}
like image 29
AranS Avatar answered Oct 20 '22 01:10

AranS