Reactjs 反应&;Redux:无限滚动导致类型错误:分派不是函数错误

Reactjs 反应&;Redux:无限滚动导致类型错误:分派不是函数错误,reactjs,redux,Reactjs,Redux,我使用react infinite scroll componentpackage在用户不断滚动(无限滚动)时加载数据。但是,当我使用Redux和其他工具进行设置时,如果滚动到底部,我的操作方法会出现以下错误: TypeError: dispatch is not a function 以下是用于复制或更多上下文的我的文件: TopRatedComponent.js: import React, { useState, useEffect } from "react"; i

我使用
react infinite scroll component
package在用户不断滚动(无限滚动)时加载数据。但是,当我使用Redux和其他工具进行设置时,如果滚动到底部,我的操作方法会出现以下错误:

TypeError: dispatch is not a function
以下是用于复制或更多上下文的我的文件:

TopRatedComponent.js:

import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { connect } from "react-redux";
import { fetchTopRatedMovies } from '../actions/topRatedAction.js';
import { Container, Row, Col, Button } from 'react-bootstrap';
import { useDispatch } from "react-redux";
import InfiniteScroll from "react-infinite-scroll-component";

const TopRatedComponent = (props) => {
    const dispatch = useDispatch();
    
    let [page, setPage] = useState(3);

    useEffect(() => {
        dispatch(fetchTopRatedMovies(page));
        setPage = page++;
    }, [])

    const { 
        topRatedMovies,
        loading,
        error
     } = useSelector(state => state.topRatedMovies);
 
    
    return (
        <div >
        {loading && <div>LOADING...</div>}
        {error && <div>{error}</div>}

        <Container className="p-4"  >
        <InfiniteScroll
          dataLength={20}
          next={fetchTopRatedMovies(page)}
          hasMore={true}
          loader={<h4>Loading...</h4>}
        >
              {topRatedMovies.results && topRatedMovies.results.map(topRated => (
            <div key={topRated.id}>
              div - #{topRated.title}
            </div>
          ))}
        </InfiniteScroll>
        </Container>

    </div>
    )
};



const mapStateToProps = state => {
    const { topRatedMovies, loading, error } = state.topRatedMovies;
    return {
        topRatedMovies,
        loading,
        error
    };
};

export default connect(
    mapStateToProps,
    {
        fetchTopRatedMovies
    }
)(TopRatedComponent);
topRatedAction.js:

import {
  FETCH_TOPRATED_START,
  FETCH_TOPRATED_FAILURE,
  FETCH_TOPRATED_SUCCESS 
} from './actionTypes'
import axios from "axios";


const API_KEY = 'MyAPIKEY';
export  const fetchTopRatedMovies = (page) => {
   // page = 1;
    const API_URL = `https://api.themoviedb.org/3/movie/top_rated?api_key=${API_KEY}&language=en-US&page=` + page;
    return dispatch => {
        dispatch(fetchTopRatedStarted());
        axios.get(API_URL)
        .then(response => {
            dispatch(fetchTopRatedSucceeded(response.data));
        })
        .catch(error =>{
            dispatch(fetchTopRatedFailed(error.message));
        });
    };
};



const fetchTopRatedStarted = () => {
  return{
      type: FETCH_TOPRATED_START,
      payload: {
          isLoading: true
      }
  };
};

const fetchTopRatedSucceeded = topRatedMovies => {
    return{
        type: FETCH_TOPRATED_SUCCESS,
        payload: {
            topRatedMovies
        }
    };
};

const fetchTopRatedFailed = error => {
    return{
        type: FETCH_TOPRATED_FAILURE,
        payload: {
            error
        }
    };
};
topRatedReducer.js

import {
    FETCH_TOPRATED_START,
    FETCH_TOPRATED_FAILURE,
    FETCH_TOPRATED_SUCCESS 
  } from '../actions/actionTypes'

  const initialState = {
      topRatedMovies: [],
      loading: false,
      error: null
  }



  export default function (state = initialState, action){

    switch (action.type) {
        case FETCH_TOPRATED_START:
            return{
                ...state,
                loading: true
            };
        case FETCH_TOPRATED_FAILURE:
            return{
                ...state,
                loading: false,
                error: action.payload.error
            }
        case FETCH_TOPRATED_SUCCESS:
            return{
                ...state,
                loading:false,
                topRatedMovies: action.payload.topRatedMovies
            };
        default:
            return state
    }

  }
然后从下一个调用无限

下一步={infinite}

然后从下一个调用无限


next={infinite}

因为您已经在使用connect并将
fetchTopRatedMovies
传递到mapDispatchToProps,所以您可以简单地从props使用dispatch函数,而不是对导入的函数调用dispatch

另外,InfiniteScroll的下一个道具不应该直接使用
fetchTopRatedMovies
,而是从道具中使用,因为thaat将是分派的函数实例。更新后的代码如下所示

const TopRatedComponent = (props) => {
    
    let [page, setPage] = useState(3);

    useEffect(() => {
        props.fetchTopRatedMovies(page);
        setPage(page => page+1); // call setPage function
    }, [])

    const { 
        topRatedMovies,
        loading,
        error
     } = props
    const fetchData = () => {
        props.fetchTopRatedMovies(page);
        setPage(page => page + 1);
    }
    
    return (
        <div >
        {loading && <div>LOADING...</div>}
        {error && <div>{error}</div>}

        <Container className="p-4"  >
        <InfiniteScroll
          dataLength={20}
          next={fetchData}
          hasMore={true}
          loader={<h4>Loading...</h4>}
        >
              {topRatedMovies.results && topRatedMovies.results.map(topRated => (
            <div key={topRated.id}>
              div - #{topRated.title}
            </div>
          ))}
        </InfiniteScroll>
        </Container>

    </div>
    )
};

const mapStateToProps = state => {
    const { topRatedMovies, loading, error } = state.topRatedMovies;
    return {
        topRatedMovies,
        loading,
        error
    };
};

export default connect(
    mapStateToProps,
    {
        fetchTopRatedMovies
    }
)(TopRatedComponent);
const TopRatedComponent=(道具)=>{
let[page,setPage]=useState(3);
useffect(()=>{
props.fetchTopRatedMovies(第页);
setPage(page=>page+1);//调用setPage函数
}, [])
常数{
排名靠前的动物,
加载,
错误
}=道具
常量fetchData=()=>{
props.fetchTopRatedMovies(第页);
设置页面(页面=>页面+1);
}
返回(
{正在加载和正在加载…}
{error&&{error}
{topRatedMovies.results&&topRatedMovies.results.map(topRated=>(
div-#{tograted.title}
))}
)
};
常量mapStateToProps=状态=>{
const{topRatedMovies,loading,error}=state.topRatedMovies;
返回{
排名靠前的动物,
加载,
错误
};
};
导出默认连接(
MapStateTops,
{
fetchTopRatedMovies
}
)(顶级组件);

import React,{useState,useffect}来自“React”;
从“react redux”导入{useSelector};
从“react redux”导入{connect};
从“../actions/topRatedAction.js”导入{fetchTopRatedMovies};
从“react bootstrap”导入{容器、行、列、按钮};
从“react redux”导入{useDispatch};
从“反应无限滚动组件”导入无限滚动;
常量TopRatedComponent=(道具)=>{
const dispatch=usedpatch();
let[page,setPage]=useState(3);
useffect(()=>{
发送(fetchTopRatedMovies(第页));
setPage(page=>page+1);//调用setPage函数
}, [])
常数{
排名靠前的动物,
加载,
错误
}=使用选择器(state=>state.topRatedMovies);
常量fetchData=()=>{
发送(fetchTopRatedMovies(第页));
设置页面(页面=>页面+1);
}
返回(
{正在加载和正在加载…}
{error&&{error}
{topRatedMovies.results&&topRatedMovies.results.map(topRated=>(
div-#{tograted.title}
))}
)
};
导出默认TopRatedComponent;//请注意,我们这里不使用connect

p.S.请注意,您不需要同时使用连接和挂钩,如useSelector和useDispatch,您可以使用其中任何一个。遵循上述任何一种方法都适用于您。

因为您已经在使用connect并传递
fetchTopRatedMovies
来映射DispatchToprops,您只需从props使用dispatch函数,而不用调用导入函数的dispatch

另外,InfiniteScroll的下一个道具不应该直接使用
fetchTopRatedMovies
,而是从道具中使用,因为thaat将是分派的函数实例。更新后的代码如下所示

const TopRatedComponent = (props) => {
    
    let [page, setPage] = useState(3);

    useEffect(() => {
        props.fetchTopRatedMovies(page);
        setPage(page => page+1); // call setPage function
    }, [])

    const { 
        topRatedMovies,
        loading,
        error
     } = props
    const fetchData = () => {
        props.fetchTopRatedMovies(page);
        setPage(page => page + 1);
    }
    
    return (
        <div >
        {loading && <div>LOADING...</div>}
        {error && <div>{error}</div>}

        <Container className="p-4"  >
        <InfiniteScroll
          dataLength={20}
          next={fetchData}
          hasMore={true}
          loader={<h4>Loading...</h4>}
        >
              {topRatedMovies.results && topRatedMovies.results.map(topRated => (
            <div key={topRated.id}>
              div - #{topRated.title}
            </div>
          ))}
        </InfiniteScroll>
        </Container>

    </div>
    )
};

const mapStateToProps = state => {
    const { topRatedMovies, loading, error } = state.topRatedMovies;
    return {
        topRatedMovies,
        loading,
        error
    };
};

export default connect(
    mapStateToProps,
    {
        fetchTopRatedMovies
    }
)(TopRatedComponent);
const TopRatedComponent=(道具)=>{
let[page,setPage]=useState(3);
useffect(()=>{
props.fetchTopRatedMovies(第页);
setPage(page=>page+1);//调用setPage函数
}, [])
常数{
排名靠前的动物,
加载,
错误
}=道具
常量fetchData=()=>{
props.fetchTopRatedMovies(第页);
设置页面(页面=>页面+1);
}
返回(
{正在加载和正在加载…}
{error&&{error}
{topRatedMovies.results&&topRatedMovies.results.map(topRated=>(
div-#{tograted.title}
))}
)
};
常量mapStateToProps=状态=>{
const{topRatedMovies,loading,error}=state.topRatedMovies;
返回{
排名靠前的动物,
加载,
错误
};
};
导出默认连接(
MapStateTops,
{
fetchTopRatedMovies
}
)(顶级组件);

import React,{useState,useffect}来自“React”;
从“react redux”导入{useSelector};
从“react redux”导入{connect};
从“../actions/topRatedAction.js”导入{fetchTopRatedMovies};
从“react bootstrap”导入{容器、行、列、按钮};
从“react redux”导入{useDispatch};
从“反应无限滚动组件”导入无限滚动;
常量TopRatedComponent=(道具)=>{
const dispatch=usedpatch();
let[page,setPage]=useState(3);
useffect(()=>{
发送(fetchTopRatedMovies(第页));
setPage(page=>page+1);//调用setPage函数
}, [])
常数{
排名靠前的动物,
加载,
错误
}=使用选择器(state=>state.topRatedMovies);
常量fetchData=()=>{
发送(fetchTopRatedMovies(第页));
设置页面(页面=>页面+1);
}
返回(
{正在加载和正在加载…}
{error&&{error}
{topRatedMovies.results&&topRatedMovies.results.map(顶部
const TopRatedComponent = (props) => {
    
    let [page, setPage] = useState(3);

    useEffect(() => {
        props.fetchTopRatedMovies(page);
        setPage(page => page+1); // call setPage function
    }, [])

    const { 
        topRatedMovies,
        loading,
        error
     } = props
    const fetchData = () => {
        props.fetchTopRatedMovies(page);
        setPage(page => page + 1);
    }
    
    return (
        <div >
        {loading && <div>LOADING...</div>}
        {error && <div>{error}</div>}

        <Container className="p-4"  >
        <InfiniteScroll
          dataLength={20}
          next={fetchData}
          hasMore={true}
          loader={<h4>Loading...</h4>}
        >
              {topRatedMovies.results && topRatedMovies.results.map(topRated => (
            <div key={topRated.id}>
              div - #{topRated.title}
            </div>
          ))}
        </InfiniteScroll>
        </Container>

    </div>
    )
};

const mapStateToProps = state => {
    const { topRatedMovies, loading, error } = state.topRatedMovies;
    return {
        topRatedMovies,
        loading,
        error
    };
};

export default connect(
    mapStateToProps,
    {
        fetchTopRatedMovies
    }
)(TopRatedComponent);
import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { connect } from "react-redux";
import { fetchTopRatedMovies } from '../actions/topRatedAction.js';
import { Container, Row, Col, Button } from 'react-bootstrap';
import { useDispatch } from "react-redux";
import InfiniteScroll from "react-infinite-scroll-component";

const TopRatedComponent = (props) => {
    const dispatch = useDispatch();
    
    let [page, setPage] = useState(3);

    useEffect(() => {
        dispatch(fetchTopRatedMovies(page));
        setPage(page => page+1); // call setPage function
    }, [])

    const { 
        topRatedMovies,
        loading,
        error
     } = useSelector(state => state.topRatedMovies);
 
    const fetchData = () => {
        dispatch(fetchTopRatedMovies(page));
        setPage(page => page + 1);
    }
    return (
        <div >
        {loading && <div>LOADING...</div>}
        {error && <div>{error}</div>}

        <Container className="p-4"  >
        <InfiniteScroll
          dataLength={20}
          next={fetchData}
          hasMore={true}
          loader={<h4>Loading...</h4>}
        >
              {topRatedMovies.results && topRatedMovies.results.map(topRated => (
            <div key={topRated.id}>
              div - #{topRated.title}
            </div>
          ))}
        </InfiniteScroll>
        </Container>

    </div>
    )
};

export default TopRatedComponent; // Note that we are not using connect here