简体   繁体   中英

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);

在此处输入图片说明

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM