Michael Podlevskykh
Michael Podlevskykh

Reputation: 245

redux-saga takeEvery only called when you click on btn, componentDidMount doesn`t call action correct

Sory for my English!

I am doing test work on React.js. The task is to make a regular blog. I ran into an unwanted problem. As a rule, componentDidMount makes entries, ready data and is called once. I invoke the loadPosts action in the CDM to get the data. The takeEvery effect sees the necessary saga, but does not cause it, but skips it. When I press a button, everything works fine.

I'm new to React. All i tried is google

repository with project branch - dev-fullapp


index.js

 import store from "./redux/store";

    const app = (
      <BrowserRouter>
        <Provider store={store}>
          <App />
        </Provider>
      </BrowserRouter>
    );

store.js

    import { createStore, compose, applyMiddleware } from "redux";
    import createSagaMiddleware from "redux-saga";
    import apiSaga from "./sagas/index";
    import rootReducer from "./reducers/index";

    const initialiseSagaMiddleware = createSagaMiddleware();

    const storeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

    const store = createStore(
      rootReducer,
      storeEnhancers(applyMiddleware(initialiseSagaMiddleware))
    );

    initialiseSagaMiddleware.run(apiSaga);
    export default store;

sagas.js

    import { put, call, takeEvery } from "redux-saga/effects";
    import { fetchGetPosts } from "../apis/index";
    import { setErrorPosts, setPosts } from "../actions/actions-posts";

    function* workerGetPosts() {
        try {
            const posts = yield call(fetchGetPosts);
        yield put(setPosts(posts));
      } catch (err) {
            yield put(setErrorPosts(err));
      }
    }

    export default function* watchSaga() {
        yield takeEvery(POSTS.LOADING, workerGetPosts);
    }

actions.js

    import { POSTS } from "../constants";

    export const loadPosts = () => {
        console.log('action-load')
        return {
        type: POSTS.LOADING
        }
    };

    export const setPosts = payload => ({
      type: POSTS.LOAD_SUCCESS,
      payload
    });

    export const setErrorPosts = error => ({
      type: POSTS.ERROR,
      error
    });

rootReducer.js

    import { combineReducers } from "redux";

    import postsReducer from "./reducer-posts";
    import loadReducer from "./reducer-load";

    const rootReducer = combineReducers({
      posts: postsReducer,
      isLoad: loadReducer
    });

    export default rootReducer;

reducer-posts.js

    import { POSTS } from "../constants";

    const postState = {
      posts: []
    };

    function postsReducer(state = postState, action) {
      switch (action.type) {
        case POSTS.LOAD_SUCCESS:
          return {
            ...state,
            posts: [...action.payload]
          };
        default:
          return state;
      }
    }

    export default postsReducer;

reducer-load.js

    import { POSTS } from "../constants";
    import { combineReducers } from "redux";

    const loadReducerPosts = (state = false, action) => {
      switch (action.type) {
            case POSTS.LOADING: return false;
            case POSTS.LOAD_SUCCESS: return true;
        case POSTS.ERROR: return false;
        default: return state;
      }
    };

    const loadReducer = combineReducers({
      isLoadPost: loadReducerPosts,
    });

    export default loadReducer;

news.jsx

    class News extends Component {
      componentDidMount() {
        loadPosts();
      }

      render() {
            CONST { loadPosts }this.props
        return (
          <main>

            // code

            <button onClick={loadPosts}>Test Button</button>
          </main>
        );
      }
    }

    const mapStateToProps = (
        { posts: { loading, posts, success } }
    ) => ({
      posts,
      loading,
      success
    });

    export default connect(
      mapStateToProps,
      { loadPosts }
    )(News);

enter image description here

Upvotes: 0

Views: 426

Answers (1)

Mobeen
Mobeen

Reputation: 985

loadPosts method is available as props to the React component in current case. Unlike in componentDidMount, on button click you are calling the function from props. You have to use this.props.loadPosts() on both places

Upvotes: 1

Related Questions