0

I'm using redux saga on a react-boilerplate open source project on github and I'm using redux saga to delete users. The code works perfectly on a create-react-app but doesn't work on the react-boilerplate (https://github.com/yarusophialiu/react-boilerplate/blob/master/app/containers/HomePage/saga.js). The thing is that the yield take(...) returns null. I console.log action.js and found that an action is dispatched when I click delete. Any help would be appreciated!!!

HomePage/saga.js

export function* deleteUser({ userId }) {
  try {
    yield call(api.deleteUser, userId);
    // yield call(getUsers);
  } catch (e) {
    console.log(e);
  }
}

export function* watchDeleteUserRequest() {
  // yield takeLatest(DELETE_USER_REQUEST, getRepos);
  while (true) {
    const action = yield take(DELETE_USER_REQUEST);
    yield call(deleteUser, {
      userId: action.payload.userId,
    });
  }
}

HomePage actions.js

export const deleteUserRequest = userId => ({
  type: DELETE_USER_REQUEST,
  payload: {
    userId,
  },
});

HomePage/index.js

...
import { createStructuredSelector } from 'reselect';

import { useInjectReducer } from 'utils/injectReducer';
import { useInjectSaga } from 'utils/injectSaga';
import { changeUsername, deleteUserRequest } from './actions';
import reducer from './reducer';
import saga from './saga';
import UserList from '../UsersPage/UserList';

const key = 'home';

export function HomePage({
  username,
  loading,
  error,
  repos,
  onSubmitForm,
  onChangeUsername,
}) {
  useInjectReducer({ key, reducer });
  console.log('home', saga);
  useInjectSaga({ key, saga });

  const [users, setUsers] = useState([]);

  useEffect(() => {
    axios
      .get('https://rem-rest-api.herokuapp.com/api/users', {
        params: {
          limit: 1000,
        },
      })
      .then(({ data }) => {
        setUsers(data.data);
      });
  }, []);

  const handleDeleteUserClick = userId => {
    console.log('delete', deleteUserRequest(userId));
    deleteUserRequest(userId);
  };

  const reposListProps = {
    loading,
    error,
    repos,
  };

  return (
    <article>
      <div>
        <UserList users={users} onDeleteUser={handleDeleteUserClick} />
      </div>
    </article>
  );
}

...

SSS
  • 3
  • 1

1 Answers1

0

Try to dispatch your action so your saga is aware of it:

import { useDispatch } from 'react-redux';

export function HomePage({
  username,
  loading,
  error,
  repos,
  onSubmitForm,
  onChangeUsername,
}) {

  const [users, setUsers] = useState([]);
  const dispatch = useDispatch(); // use to dispatch actions

  ...

  const handleDeleteUserClick = userId => {
    dispatch(deleteUserRequest(userId)); // Here you need to use dispatch
  };

  ...

  return (
    <article>
      <div>
        <UserList users={users} onDeleteUser={handleDeleteUserClick} />
      </div>
    </article>
  );
}

Also, your saga should listen to actions and update the reducer:

export function* deleteUser({ userId }) {
  try {
    yield call(api.deleteUser, userId);
    yield put({ type: 'DELETE_USER_SUCCESS', payload: { userId });
  } catch (e) {
    console.log(e);
  }
}

export function* watchDeleteUserRequest() {
  yield takeLatest(DELETE_USER_REQUEST, deleteUser);
}

Then your reducer should update the state:

const initialState = {
    users: []
};

const handlers = {
    ['DELETE_USER_SUCCESS']: (state, payload) => {
        const users = [...state.users.filter(user => user.id !== payload.id);
        return { ...state, users: { ...state.pending, invite: false } };
    }
};

This should handle your scenario, let me know if it is working Welcome to Stack Overflow

Tomer
  • 1,335
  • 1
  • 12
  • 22
  • Yes, it works! Thank you so much! The only thing I'm confused about is dispatch. I got **index.js?2433:54 Uncaught TypeError: Object(...) is not a function** when using ```const dispatch = useDispatch();``` so I dispatched through mapDispatchToProps. I looked up online and tried different versions of react and react-dom like ^16.7.2, 16.8.0, next etc. but no luck. Any idea about this:)? – SSS Dec 17 '19 at 20:03
  • @SSS - Glad it works :), Have you imported it correctly? `import { useDispatch } from 'react-redux';` – Tomer Dec 17 '19 at 20:19
  • @SSS - that might happen because reat-redux package is outdated, make sure you are using react-redux v7.1.0. – Tomer Dec 19 '19 at 07:32