How to show updated array of object list item when state is update in reducer using redux-saga?

Viewed 365

I am unable to show the updated array of object list items when the state is updated in reducer using redux-saga. Basically, I am creating a different category for a shopping cart. After creating, I am not seeing the update list. When I change route and comeback to place where I am creating category then only I am able to see the updated category list. Something useEffect or while dispatch action not working properly. The source code is as follows:

category.action.js

import { takeLatest, call, put, all, delay } from "redux-saga/effects";

import CategoryActionTypes from "./category.types";

import {
  loadCategorySuccess,
  loadCategoryFail,
  createCategorySuccess,
  createCategoryFail,
} from "./category.actions";

import { getCategories, createCategory } from "../../actions/category";

export function* fetchCategory(action) {
  try {
    delay(500);
    const response = yield call(getCategories, "");
    yield put(loadCategorySuccess(response.data));
  } catch (error) {
    yield put(loadCategoryFail(error.response.data));
  }
}

export function* createCategoryAsync({ payload: { name, token } }) {
  try {
    console.log("===name", name);
    console.log("===token", token);
    const response = yield call(createCategory, { name }, token);
    yield put(createCategorySuccess(response.data.name));
    delay(500);
  } catch (error) {
    yield put(createCategoryFail(error.response.data));
  }
}

export function* fetchCategoryStart() {
  yield takeLatest(CategoryActionTypes.LOAD_CATEGORY_START, fetchCategory);
}

export function* createCategoryStart() {
  yield takeLatest(
    CategoryActionTypes.CREATE_CATEGORY_START,
    createCategoryAsync
  );
}

export function* categorySagas() {
  yield all([call(fetchCategoryStart), call(createCategoryStart)]);
}

category.reducer.js

import CategoryActionTypes from "./category.types";

const INITIAL_STATE = {
  categoryName: "",
  categories: [],
  error: false,
  errorMsg: "",
};

const categoryReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case CategoryActionTypes.LOAD_CATEGORY_START:
      return {
        ...state,
        loading: true,
      };
    case CategoryActionTypes.LOAD_CATEGORY_SUCCESS:
      return {
        ...state,
        loading: false,
        categories: action.payload,
      };
    case CategoryActionTypes.LOAD_CATEGORY_FAIL:
    case CategoryActionTypes.CREATE_CATEGORY_FAIL:
      return {
        ...state,
        loading: false,
        error: true,
        errorMsg: action.payload,
      };
    case CategoryActionTypes.SET_CATEGORY_EMPTY:
      return {
        ...state,
        categoryName: "",
      };
    case CategoryActionTypes.CREATE_CATEGORY_START:
      return {
        ...state,
        loading: true,
      };
    case CategoryActionTypes.CREATE_CATEGORY_SUCCESS:
      return {
        ...state,
        loading: false,
        categoryName: action.payload,
      };
    default:
      return state;
  }
};

export default categoryReducer;

Category.js

const CategoryCreate = () => {
  const [name, setName] = useState("");

  const dispatch = useDispatch();

  useEffect(() => {
// working fine for initial category load 
    dispatch(loadCategoryStart());
  }, []);

  const { categories, loading, categoryName, error, errorMsg } = useSelector(
    (state) => ({
      ...state.category,
    })
  );
  const {
    user: { token },
  } = useSelector((state) => ({ ...state }));

  const handleSubmit = (e) => {
    e.preventDefault();
    dispatch(setCategoryEmpty());
    let load = true;
    dispatch(createCategoryStart({ name, token }));
    if (!error) {
      toast.success(`${name} is created`);
      setName("");
      // after successfully created category, i am trying get updated category list to reflect on UI but it is not working. When i change route and comeback to place where i am creating category then only i am able to see the updated category list.
      dispatch(loadCategoryStart());
    } else {
      toast.error(errorMsg);
    } 
  };
  return (
<>
 <form onSubmit={handleSubmit}>
    <div className="form-group">
      <label>Name</label>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        className="form-control"
        autoFocus
        required
      />
      <br />
      <button className="btn btn-outline-primary">Save</button>
       
       <hr />
        {categories &&
          categories.length &&
          categories.map((c) => (
            <div key={c._id} className="alert alert-secondary">
              {c.name}{" "}
            </div>
          ))}
    </div>
  </form>
</>
)
0 Answers
Related