React: useReducer's dispatch

Created on 9 Mar 2019  路  8Comments  路  Source: facebook/react

useReducer's dispatch() function is not processing the action triggered by some of my components. I imported useReducer locally inside of each of my 3 components. The dispatch() inside the parent component is working but not in 2 child components. I tried to make the parent component the only source of dispatch() and pass it to the 2 child components as a prop (props.dispatch) but it didn't work as well.

Needs More Information

Most helpful comment

@jstarnate the reducer that you are using in different components will mount different hooks.

Works like a charm https://codesandbox.io/s/5zvw3xm58n

In addition to the above way, if you do not comfort to pass dispatch as a prop to children, you can use context API.

All 8 comments

We can't help without reproduction. Try https://codesandbox.io/s/new

Can this issue be closed if resolved

Sorry for my late response (due to busyness).
@miraage Is it the only way? Should the parent component always be the only source?

Here's the code:

state.js (initial state)
export default { count: 0 };

reducer.js

export default (state, action) => {
    switch (action.type) {
        case 'increment':
            return { count: state.count + 1 };

        case 'decrement':
            return { count: state.count - 1 };

        default:
            return state;
    }
}

App.js

import React from 'react';
import Increment from 'path/to/IncrementComponent';
import Decrement from 'path/to/DecrementComponent';
import initialState from 'path/to/initialState';

export default function() {
    return (
        <section>
            <Increment />
            <Decrement />
            <h1>{initialState.count}</h1>
        </section>
    )
}

Increment.js

import React, { useReducer } from 'react';
import reducer from 'path/to/reducer';
import initialState from 'path/to/initialState';

export default function() {
    const [ state, dispatch ] = useReducer(reducer, initialState);

    function increment() {
        dispatch({ type: 'increment' });
    }

    return (
        <button onClick={increment}>Increment</button>
    );
}

Decrement.js

import React, { useReducer } from 'react';
import reducer from 'path/to/reducer';
import initialState from 'path/to/initialState';

export default function() {
    const [ state, dispatch ] = useReducer(reducer, initialState);

    function decrement() {
        dispatch({ type: 'decrement' });
    }

    return (
        <button onClick={decrement}>Decrement</button>
    );
}

No errors logged but still not working. And the location of files is not an issue.

@jstarnate https://reactjs.org/docs/lifting-state-up.html
Not quite the hooks way, but idea is the same.

@jstarnate the reducer that you are using in different components will mount different hooks.

Works like a charm https://codesandbox.io/s/5zvw3xm58n

In addition to the above way, if you do not comfort to pass dispatch as a prop to children, you can use context API.

Thanks, guys! Maybe Redux is still the better solution for this case.

Was this page helpful?
0 / 5 - 0 ratings