Skip to content
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

Dynamically change hooks after first render #49

Closed
dashed opened this issue Aug 21, 2017 · 5 comments
Closed

Dynamically change hooks after first render #49

dashed opened this issue Aug 21, 2017 · 5 comments
Assignees

Comments

@dashed
Copy link

dashed commented Aug 21, 2017

I was playing with this library on a toy side-project, and I noticed I cannot dynamically change hooks, especially after the first render.

The gist of the code I had is as follows:

import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";

import { compose, withState } from "recompose";

// fake data generator
const getItems = count =>
    Array.from({ length: count }, (v, k) => k).map(k => ({
        id: `item-${k}`,
        content: `item ${k}`,
        type: generateType(k)
    }));

// ...

const onDragEnd = setCards => result => {
    // dropped outside the list
    if (!result.destination) {
        return;
    }

    setCards(prevCards => {
        const nextCards = reorder(
            prevCards,
            result.source.index,
            result.destination.index
        );
        return nextCards;
    });
};

const Board = props => {
    const { cards, setCards } = props;

    return (
        // NOTE: unable to replace onDragEnd after first render
        <DragDropContext onDragEnd={onDragEnd(setCards)}>
            <Droppable droppableId="droppable">
                {generateBoard(cards)}
            </Droppable>
        </DragDropContext>
    );
};

const cardsState = withState("cards", "setCards", getItems(10));

export default compose(cardsState)(Board);

Even though the drag and drop (which is awesome by the way) appears to work fine, after the first render, the generated function from onDragEnd(setCards) is not replaced within DragDropContext.

This is likely to do with the fact there is no componentWillReceiveProps() (or similar) at

export default class DragDropContext extends Component {
/* eslint-disable react/sort-comp */
props: Props
store: Store
// Need to declare childContextTypes without flow
// https://github.com/brigand/babel-plugin-flow-react-proptypes/issues/22
static childContextTypes = {
[storeKey]: PropTypes.shape({
dispatch: PropTypes.func.isRequired,
subscribe: PropTypes.func.isRequired,
getState: PropTypes.func.isRequired,
}).isRequired,
}
/* eslint-enable */
componentWillMount() {
this.store = createStore(this.props);
}
getChildContext(): Context {
return {
[storeKey]: this.store,
};
}
render() {
return this.props.children;
}
}


Even though the above example uses recompose, one may refactor the above to use redux and friends (e.g. react-redux), whereby the developer can pass dispatch (or a binded dispatch) to onDragEnd(). You cannot really assume dispatch won't change after the first render.

@alexreardon
Copy link
Collaborator

alexreardon commented Aug 21, 2017

This behaviour is currently not supported:

Dynamic hooks

Your hook functions will only be captured once at start up. Please do not change the function after that. If there is a valid use case for this then dynamic hooks could be supported. However, at this time it is not.

-> README.md

The functions are passed onto a redux middleware at startup and not looked at again. This could be improved for sure. This looks like a valid use case.

@alexreardon
Copy link
Collaborator

This should be fairly easy to do - we just need to move away from using a redux middleware and set up a subscription to the store within the DragDropContext component.

@alexreardon alexreardon removed this from the Candy Castle milestone Sep 20, 2017
@alexreardon alexreardon self-assigned this Sep 25, 2017
@alexreardon
Copy link
Collaborator

I am fiddling with this while away :)

@alexreardon
Copy link
Collaborator

This has now shipped @dashed. Enjoy!

@dashed
Copy link
Author

dashed commented Oct 9, 2017

@alexreardon thanks for taking the time to look into this! 😄 I'll definitely check it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants