【问题标题】:redux hook fetch data from API with action in separate fileredux 挂钩从 API 获取数据,并在单独的文件中执行操作
【发布时间】:2021-02-21 17:48:47
【问题描述】:

我正在从库“react-redux”中学习 redux 钩子,因为我还需要在项目的功能组件中应用 Redux。

到目前为止,我不明白如何将 redux HOC 的相同项目结构与我用于类组件的 connect 一起使用。

具体来说,我有一个单独的操作文件,它使用 axios 调用我的 API:

FoosActions.js

import axios from "axios";
import {
  GET_FOO,
} from "./Types";

};

export const getFoo = () => async (dispatch) => {
  const res = await axios.get("/api/v1/foos");
  dispatch({
    type: GET_FOO,
    payload: res.data,
  });
};


FooList.js:

import { connect } from "react-redux";
import { getFoos } from "../../actions/FoosActions";

class FoosList extends Component {
  constructor() {
    super();

    this.state = {
      errors: {},
    };
  }
  componentDidMount() {
    this.props.getFoos();
  }
  
   render() {
    const { data } = this.props.foo;       
    return (

        <div className="container">
            <h2>foo data fetched from API endpoint  : </h2>
            <ul>
              {data.map((foo) => {
                return (
                    <li>
                      {foo.id} - {foo.name}
                    </li>
                );
              })}
              <ul>
            </div>
          </div>
        </div>
       
    );
  }
}

  const mapStateToProps = (state) => ({
    foo: state.foo,
    errors: state.errors,
  });

export default connect(mapStateToProps, { getFoos })(FooList);

FooReducer,js

import { GET_FOO} from "../actions/Types";

const initialState = {
  foos: [],

};

export default function (state = initialState, action) {
  switch (action.type) {
    case GET_FOO:
      return {
        ...state,
        foos: action.payload,
      };

现在改为在我的功能组件中: FooListFC.js

import { useDispatch, useSelector } from "react-redux";
import { getFoo } from "../../actions/FoosActions";
const Mapping = (props) => {
    
  const [foo, setFoo] = useState([]);
  const dispatch = useDispatch();
  

  useEffect(() => {
    dispatch(getFoo());
    const fooRetrieved = useSelector((state) => state.foo);
    setFoo(fooRetrieved);
  }, []);
    
    return (
      <div className="container">
         <h2>foo data fetched from API endpoint  : </h2>
            <ul>
              {foo.map((foo) => {
                return (
                    <li>
                      {foo.id} - {foo.name}
                    </li>
                );
              })}
            </ul>
      </div>
    )

}

如何重现从类组件中的 API 获取数据的相同行为,并使用不同文件中的操作并使用 redux 挂钩(我在功能组件中的代码不起作用)?

在同一个项目中同时使用这两种方法是一种不好的做法吗?

【问题讨论】:

    标签: reactjs redux react-redux redux-thunk


    【解决方案1】:

    您可以重现相同的行为,在功能组件中您只能使用选择器而不是 useSelectoruseState

    const Mapping = (props) => {
        
      const foo = useSelector((state) => state.foo);
      const dispatch = useDispatch();
      
      useEffect(() => {
        dispatch(getFoo());
      }, []);
    
      ...
    

    【讨论】:

    • 我刚刚尝试了您的建议,但 foo 始终未定义,事实上除非我在 foo.map() 之前进行检查,否则我会收到错误消息。在我执行调度(getFoo())之后似乎没有调用useSelector,这可能吗?
    • 感谢您以您的方式完成的 dispatch() 最终 redux 在开发工具中显示了状态树。唯一的问题是 useSelector 没有检索任何内容
    • react-dom.development.js:22665 Uncaught TypeError: foo.map is not a function
    • useSelector 应在 foo 更改时调用(应该像您在类组件中所期望的那样工作),对于未定义的问题,如果您在减速器中使用初始值,就像在您的示例中一样,它应该返回[]
    • 我不得不做 useSelector((state) => state.foo.foos);因为我的减速机!谢谢!我也可以在 useSelector 的结果上使用 useCallback 吗?我想让 foo 被记忆
    猜你喜欢
    • 2023-04-03
    • 2014-04-14
    • 1970-01-01
    • 2020-09-17
    • 2017-09-11
    • 1970-01-01
    • 2021-07-19
    • 2011-08-26
    • 1970-01-01
    相关资源
    最近更新 更多