is it possible to change the initial state of reducer after state changed and use it ? React
Asked Answered
P

2

7

I just wanna know is it possible to use useReducer, as I use it inside UseEffect fetched data => State => useReducer(..., State)

 const [initialData, setInitialData] = useState({ name: 'ass' });
    const [data, dispatch] = useReducer(apiReducer, initialData);

    const Data2 = useFetch('/qaz')

    useEffect(() => {
        setInitialData(Data2)
    }, [Data2])

    useEffect(() => {
        dispatch({ type: 'Different', payload: 'key' })
    }, [initialData])


export function apiReducer(state, action) {
    switch (action.type) {
        case 'Different':
            return { ...state, key: action.payload };
        default:
            return state
    }
}
Pear answered 24/3, 2021 at 21:58 Comment(0)
C
9

You cannot change the initial state after the reducer has been created. What you can do is dispatch an action that replaces the entire state. You can use a useEffect hook to dispatch this "REPLACE_STATE" action after the useFetch hook has returned its data.


Reducer

export function apiReducer(state, action) {
  switch (action.type) {
    case "REPLACE_STATE":
      return action.playload;
    case "Different":
      return { ...state, key: action.payload };
    default:
      return state;
  }
}

Component

export default function App() {
  const [state, dispatch] = useReducer(apiReducer, { name: "ass" });

  const fetchedData = useFetch("/qaz");

  useEffect(() => {
    if (fetchedData) {
      dispatch({ type: "REPLACE_STATE", payload: fetchedData });
    }
  }, [fetchedData]);

  const doSomething = () => {
    dispatch({ type: "Different", payload: "key" });
  };
...
Cardigan answered 25/3, 2021 at 3:31 Comment(2)
Can't thank enough, it was fully useful. Below I answer what I actually need.Pear
I lol'd at the test data. Great answer. Can I ask where you found in the docs how it handles a changing initializer?Elyn
P
0
export default function App() {
  const [state, dispatch] = useReducer(apiReducer, { name: "ass" });
  const [change, setChange] = useState(false)
  const fetchedData = useFetch("/qaz");

  useEffect(() => {
    if (fetchedData) {
      dispatch({ type: "REPLACE_STATE", payload: fetchedData });
      setChange(!change)
    }
  }, [fetchedData]);

  useEffect(() => {
    dispatch({ type: "Different", payload: "key" });
  },[change]);
Pear answered 25/3, 2021 at 13:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.