antonwilhelm
antonwilhelm

Reputation: 7493

Accessing & Relying on Props inside useReducer an Anti-Pattern?

I have a component App() which takes some props, called data. That App component manages its state via useReducer. Depending on the state of my reducer, I show/hide certain data from the data prop. My reducer also calculate new state depending on what's in data. So for example, to get a new id, my reducer needs to go through data and find the next id.

const App = ({ data }) => {
    //...
    const reducer = 
        (state, action) => {
            switch (action.type) {
                case 'NEXT_TAB': {
                    let nextTabIndex = state.activeTab + 1;
                    let nextId = data.tabs[nextTabIndex].id; //<==== Worried about this line here, accessing data prop

                    return {
                        ...state,
                        state.activeTabId: nextId
                    };
                }
                default:
                    return state;
            }
        }
       //....
       const [myState, dispatch] = useReducer(reducer, state);
       //....

As I implemented it here, my App component receives data as props.

In my reducer, I access those props:

let nextId = data.tabs[nextTabIndex].id

My question is whether this goes against the idea of a reducer to work with & utilise the received props? I could, alternatively, pass the data props to my reducer, every time I call an action. However, I am worried that this will make everything slower and unnecessarily complex?

Upvotes: 3

Views: 806

Answers (1)

tmarwen
tmarwen

Reputation: 16354

Although there might be nothing wrong with your approach if, unlikely to be true, your application consisted only of the App component.

Redux idea, and the Flux architecture pattern, aims to centralize state management within a single backbone component, the store. The clear, and very legitimate, intent and goal behind this is to reduce state management complexity as your application grows over and over in size.

The way you go, with a reducer declared within your component and tightly coupled to your component props, will likely lead to unpredictable results and a lot of scaling complexity once one (or more other) component will use / depend on the state.activeTabId property.

You can read more on Redux development guidelines, and more specifically, on a rule you are violating by depending on local component props:

Reducer functions should only depend on their state and action arguments, and should only calculate and return a new state value based on those arguments. They must not execute any kind of asynchronous logic (AJAX calls, timeouts, promises), generate random values (Date.now(), Math.random()), modify variables outside the reducer, or run other code that affects things outside the scope of the reducer function.

Upvotes: 1

Related Questions