使用带有react redux的钩子。减速器未受压。无状态

时间:2020-01-24 20:11:51

标签: reactjs redux react-hooks

我正在使用带钩子的redux开发一个React应用程序。 这是我的动作创建者

    PostAction
    ***********
    import * as types from "./actionTypes";
    import axios from 'axios';

    const ROOT_URL = 'http://dotsuper.com/api'

    export function fetchPosts(){
        const request = axios.get(`${ROOT_URL}/post/getposts`)

        return {
            type: types.GETALL_POSTS,
            payload: request
        }
    }

这是我下面的减速器

    PostReducer
    ************

    import _ from 'lodash';
    import * as types from "../actions/actionTypes";

    export default function postReducer(state = [], action) {
      switch (action.type) {
        case types.GETALL_POSTS:
          debugger;
          console.log(action.payload.data);
          return _.mapKeys(action.payload.data, 'id');
        default:
          return state;
      }
    }

这是我的商店配置的样子

    configureStore
    ***************
    import { createStore, applyMiddleware, compose } from "redux";
    import rootReducer from "./reducers";
    import reduxImmutableStateInvariant from "redux-immutable-state-invariant";
    import thunk from 'redux-thunk';

    export default function configureStore(initialState) {
      const composeEnhancers =
        window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; //add support for redux dev tools.
      return createStore(
        rootReducer,
        initialState,
        composeEnhancers(applyMiddleware(thunk, reduxImmutableStateInvariant()))
      );
    }

这是我的组件的样子。

我的问题是,当我查看我的devtools时,发布状态为 完全空了。设置调试器时,PostReducer没有受到攻击。我想我还是 遗漏了什么。我认为您不能使用带有钩子的连接。我下面需要做什么 拥有我的状态的数据并能够击中我的减速器?

    PostPage
    **************

    import React, { useState, useEffect } from "react";
    import {fetchPosts} from "../../redux/actions/postActions"; 


    const PostsPage = () => {
        const [getPosts, setGetPosts] = useState([]);


        async function fecthData(){
            const res = fetchPosts()
        }

        useEffect( () => {
            fecthData();
        },[]);


        return (
            <div>
                <h2>Posts</h2>
                <p>
                This page is for all the posts.
                </p>
            </div>
        );
    }

    export default PostsPage;

enter image description here

2 个答案:

答案 0 :(得分:0)

您正在组件内部调用动作生成器fetchPosts(),但实际上您从未将任何更改分派到您的状态。如果仔细观察,您会发现fetchPosts()返回的对象通常称为操作:

{
   type: types.GETALL_POSTS,
   payload: request
}

因此,基本上,当您调用fetchPosts时,会获取内容并返回此对象。 到目前为止,尚未触及Redux状态

下一步,您实际上应该采取这个对象并将其分发到您的商店,如下所示:

    const action = await fetchPosts();
    dispatch(action);

当您将mapDispatchToProps与connect一起使用时,connect会为您处理。

选中here,以更好地理解该概念。


但是,当与钩子一起使用时,可以从react-redux导入它们:

useDispatch而不是mapDispatchToProps

useSelector而不是mapStateToProps

import {useDispatch, useSelector} from 'react-redux';
import myAction from 'path/to/my/action';

const MyComponent = (props) => {
    const myState = useSelector(state => state.myState);
    const dispatch = useDispatch();

    const handleClick = () => {
        dispatch(myAction());
    }

    return (
        ...
    )
}

答案 1 :(得分:0)

  1. fetchPosts方法中进行检查,axios.get返回promise。你需要做 异步方法和处理异步数据。

  2. 您需要分派动作,以便将动作绑定到redux状态。

    // PostAction

    import * as types from "./actionTypes";
    import axios from 'axios';

    const ROOT_URL = 'http://dotsuper.com/api'

    export function fetchPosts(){
        return async (dispatch) => {
          const request = await axios.get(`${ROOT_URL}/post/getposts`); // returns promise.

          dispatch({
             type: types.GETALL_POSTS,
             payload: request
          }); 
        }
    }

    // PostPage

    import React, { useState, useEffect } from "react";
    import {useDispatch} from "react-redux";
    import {fetchPosts} from "../../redux/actions/postActions"; 


    const PostsPage = () => {
        const [getPosts, setGetPosts] = useState([]);

        const dispatch = useDispatch();

        useEffect( () => {
            dispatch(fetchPosts());
        },[]);


        return (
            <div>
                <h2>Posts</h2>
                <p>
                This page is for all the posts.
                </p>
            </div>
        );
    }

    export default PostsPage;