-1

I have the following code to define a React Reducer function:

import { useReducer, Reducer } from 'react';
interface IArrowState {
  ascending: [
    { time: boolean },
    { user: boolean }
  ]
}

type ArrowAction = {
  type: string;
}

const Events: FC<IEventComponent> & {getLayout: (params: any) => void;} = () => {
  const arrowInitialState: IArrowState = {
    ascending: [
      { time: true },
      { user: true }
    ]
  }

  const arrowReducer: Reducer<IArrowState, ArrowAction> = (state, action) => {
    switch (action.type) {
      case 'time':
        return state.ascending['time'] = !state.ascending['time'];
      case 'user':
        return state.ascending['user'] = !state.ascending['user'];
    }
  }
}

However I'm getting TS2322 Type A is not assignable to type B error on line const arrowReducer: Reducer<IArrowState, ArrowAction>:

enter image description here

Can someone explain what is going wrong here? Should I give a return type to Reducer<IArrowState, ArrowAction>?

Lin Du
  • 88,126
  • 95
  • 281
  • 483
one-hand-octopus
  • 2,229
  • 1
  • 17
  • 51

1 Answers1

1

You didn't update the state correctly, you must do the immutable update for the state in the reducer function. See immutable-update-patterns

import type { Reducer } from 'react';

interface IArrowState {
    ascending: [
        { time: boolean },
        { user: boolean }
    ]
}

type ArrowAction = {
    type: string;
}

const arrowInitialState: IArrowState = {
    ascending: [
        { time: true },
        { user: true }
    ]
}

const arrowReducer: Reducer<IArrowState, ArrowAction> = (state, action): IArrowState => {
    const [time, user] = state.ascending;
    switch (action.type) {
        case 'time':
            return {
                ...state,
                ascending: [{ time: !time.time }, user]
            }
        case 'user':
            return {
                ...state,
                ascending: [time, { user: !user.user }]
            }
        default:
            return state;
    }
}

const nextArrowState = arrowReducer(arrowInitialState, { type: 'time' });
console.log('nextArrowState: ', nextArrowState);

TS Playground(Click "Run" to check the logs in right panel)

Lin Du
  • 88,126
  • 95
  • 281
  • 483