question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal: Component level state reducer

See original GitHub issue

I understand component level state has be discussed quite in-depth here but I was wondering if this proposed API might be considered. It’s probably a little too messy with the underlying implementation having to create unique ID’s for each component and be the same ID every time (for time travel etc.) but worth the discussion I feel (and as the CONTRIBUTING.md says to discuss before wasting my time implementing).

What I’m proposing is adding another argument to the connect function that allows you to specify a reducer for the component’s state. This state would then be accessed via a state prop (or another more appropriate name if that identifier is already taken).

Example:

import React, { Component } from "react";
import { connect } from "react-redux";

class Login extends Component {
    render() {
        const { state } = this.props;

        if(state.error) {
            // Error like "Invalid credentials"
            return <p>{ state.error.message }</p>
        }

        return //...form
    }
}

const componentReducer = (state = {}, action) => {
    switch action.type {
        case "USER_LOGIN_FAILURE": // Listen to any actions
            // Set the `error` key in the component's state
            return { error: action.error }

        default:
            return state;
    }
}

export default connect(mapStateToProps, actions, componentReducer)(Login)
Problems
  • ID’s for components need to be generated in a deterministic way (hash the global state and component index?).
  • Dispatching actions that are intended for only one component would require some sort of instance of ID comparison. For example, you couldn’t just dispatch a DROPDOWN_SELECT because all dropdowns mounted would then have the same selection.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:13 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
lucasconstantinocommented, Mar 9, 2017

Came up with something easy here:

import { connect } from 'react-redux'
import { compose, withProps } from 'recompose'
import { createAction } from 'redux-actions'

export const WITH_REDUCER = 'withReducer/WITH_REDUCER'
export const withReducerAction = createAction(WITH_REDUCER)

export const withReducer = reducers => compose(
  connect(),
  withProps(props => Object.keys(reducers).reduce(
    (newProps, name) => ({
      ...newProps,
      [name]: payload => props.dispatch(withReducerAction({
        reducer: reducers[name],
        payload,
        props,
      }))
    }), {}
  ))
)

export default (state, { type, payload: { reducer, props, payload } }) =>
  type === WITH_REDUCER ? reducer(props)(state, { type, payload }) : state

Add the exported reducer to the store, and use the helper as such:

const Comp = ({ myComponentReducer, state }) => (
  <div>
    <p>{ state }</p>
    <input type="text" onChange={ (e) => myComponentReducer(e.value) } />
  </div>
)

const myComponentReducer = props => (state, { payload }) => payload

export default compose(
  connect(state => ({ state })),
  withReducer({ myComponentReducer })
)(Comp)

Quite nice… I’ll make a module soon.

0reactions
Wroudcommented, Apr 8, 2018
Read more comments on GitHub >

github_iconTop Results From Across the Web

Redux Fundamentals, Part 3: State, Actions, and Reducers
Reducers are functions that take the current state and an action as arguments, and return a new state result. In other words, (state,...
Read more >
A Redux State organization proposal | by Arol - Medium
This state is created using combineReducers to define separate state parts to be controlled by different reducers.
Read more >
Many components with the same reducer but different initial ...
I would like to create another Monster component but with different initial state but who works with the same reducer.
Read more >
redux-component-state - npm
Component level state's manager using redux reducers to support on-demand store creation. This project is born to satisfy some requirement for ...
Read more >
Extracting State Logic into a Reducer - React Docs
As this component grows, so does the amount of state logic sprinkled throughout it. To reduce this complexity and keep all your logic...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found