Search code examples
javascriptnode.jstypescriptwebredux

useSelector not updating values, and not triggering useEffect but value can be read using store (redux)


I've been using Redux for quite some time now but for some reason my code just doesn't work:

import { store } from "../pages/_app";
....
  const dispatch = useDispatch();
  const [state_sample, setSs]: any = useState(0); // - just use for triggering useEffect
  const audioCurrentTimeState: any = useSelector((state: RootState) => {
    state.AudioCurrentTimeState;
  });

  useEffect(() => { // - I am trying to trigger this useEffect but it doesn't work
    console.log(audioCurrentTimeState); // - doesn't work (?)
    console.log(store.getState().AudioCurrentTimeState); // - works
  }, [audioCurrentTimeState, state_sample]);

  return (
    <div className={style.waveform_component_root}>
      <p
        onClick={() => {
          console.log("clicked!");
          setSs(Math.random()); // - just use for triggering useEffect
          dispatch({
            type: "AudioCurrentTimeReducer/SET",
            value: Math.random(),
          });
        }}
      >
        click me
      </p>
   </div>)

Here is the reducer of audioCurrentTimeState :

export const AudioCurrentTimeReducer = (value = 0, action: any) => {
  switch (action.type) {
    case "AudioCurrentTimeReducer/SET":
      return action.value;
    default:
      return value;
  }
};

Here is rootState :

import { combineReducers } from "redux";
import {
  AudioCurrentTimeReducer,
} from "./reducers/reducers";

const rootReducers = combineReducers({
  AudioCurrentTimeState: AudioCurrentTimeReducer,
});

export type RootState = ReturnType<typeof rootReducers>;

export default rootReducers;

And I setup by redux like this :

import type { AppProps } from "next/app";
import { createStore } from "redux";
import { Provider } from "react-redux";
import rootReducers from "../scripts/redux/rootReducer";

export const store = createStore(rootReducers);

export default function App({ Component, pageProps }: AppProps) {
  return (
    <Provider store={store}>
      <Component {...pageProps} />
    </Provider>
  );
}

I've never encountered this issue before, and I can't seem to find any references if there are any changes. But as you can see from above I can only get the value of AudioCurrentTimeState if I call it by store.getState().AudioCurrentTimeState not by useSelector and I need to trigger the useEffect for this.


Solution

  • You forgot to return the value in the useSelector

    correct:

      const audioCurrentTimeState: any = useSelector((state: RootState) => {
        RETURN state.AudioCurrentTimeState;
      });
    
    // OR short
      const audioCurrentTimeState: any = useSelector((state: RootState) => state.AudioCurrentTimeState);
    
    

    was:

      const audioCurrentTimeState: any = useSelector((state: RootState) => {
        state.AudioCurrentTimeState;
      });