-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Proposal: Component level state reducer #275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'd like to see a proof of concept for this. |
Sweet, I'll get on it. |
I've put together a quick and dirty implementation if you want to play around with it:
|
This can certainly live in user land - example |
Hello, |
i'd also like it to be more easy to mount local state in redux store. See also: https://github.com/threepointone/redux-react-local |
In our applications we solved this problem in connect-like style. https://github.com/Babo-Ltd/redux-state |
See also (for inspiration): |
We have solved this in |
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. |
Im implementing this in my project, example below from here. rootReducers.forEach(reducer => {
reducer.components.forEach(component => {
component.setState((prevState, props) => reducer.reducer(props, prevState, action));
});
}); Layout.ts export class LayoutClass extends React.Component {
render() {
return
(
<NavMenu switchDrawer={this.props.actions.switchDrawer} key={"drawer"} />
);
}
}
const enhance = compose(
withRouter,
connect(
null,
lecturersActions.mapDispatch.ui,
),
);
export const Layout = enhance(LayoutClass); DrawerWraper.ts const initState = {
open: true,
};
export class DrawerWraperClass extends React.Component {
constructor(props) {
super(props);
this.state = initState;
}
closeDrawer = () => {
this.setState({ open: false });
}
openDrawer = () => {
this.setState({ open: true });
}
render() {
return (
<Drawer
persistent={true}
open={this.state.open}
onClose={this.closeDrawer}
onOpen={this.openDrawer}
>
...
</Drawer>
);
}
}
const switchDrawer = (props, prevState) => ({ open: !prevState.open });
const stateReducer = reducer => reducer
.on(lecturersActions.actions.ui.switchDrawer, switchDrawer);
const enhance = compose(
withRouter,
connectState(
initState,
stateReducer,
"drawer",
),
);
export const DrawerWrapper = enhance(DrawerWraperClass); |
Forgot to mention: I have indeed published a package for this: https://github.com/lucasconstantino/redux-transient @Wroud perhaps you could give an opinion on that :) |
published a package https://github.com/Wroud/redux-subreducer |
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 astate
prop (or another more appropriate name if that identifier is already taken).Example:
Problems
DROPDOWN_SELECT
because all dropdowns mounted would then have the same selection.The text was updated successfully, but these errors were encountered: