如何解决React / TypeScript / Redux / Thunk reducer被触发,但状态未在Redux存储中更新
我正在尝试使用API中的流派列表填充Redux存储状态,我可以获取要分派给reducer的操作,但是reducer似乎没有更新状态,因为我的console.log位于src / components / MovieForm.tsx返回默认状态“ null”,而不是流派数组,我不知道为什么,我试图查看状态是否在src / components / MovieForm.tsx中的setInterval中更新。记录状态,也许问题是我如何访问状态?这些是文件:
src / actions / movieActions.ts:
import { ActionCreator,Dispatch } from 'redux';
import { ThunkAction } from 'redux-thunk';
import { IMovieState } from '../reducers/movieReducer';
import axios from 'axios';
export enum MovieActionTypes {
ANY = 'ANY',GENRE = 'GENRE',}
export interface IMovieGenreAction {
type: MovieActionTypes.GENRE;
genres: any;
}
export type MovieActions = IMovieGenreAction;
/*<Promise<Return Type>,State Interface,Type of Param,Type of Action> */
export const movieAction: ActionCreator<ThunkAction<Promise<any>,IMovieState,void,IMovieGenreAction>> = () => {
return async (dispatch: Dispatch) => {
try {
console.log('movieActions called')
let res = await axios.get(`https://api.themoviedb.org/3/genre/movie/list?api_key=${process.env.REACT_APP_MOVIE_API_KEY}&language=en-US`)
console.log(res.data.genres)
dispatch({
genres: res.data.genres,type: MovieActionTypes.GENRE
})
} catch (err) {
console.log(err);
}
}
};
src / reducers / movieReducer.ts:
import { Reducer } from 'redux';
import { MovieActionTypes,MovieActions } from '../actions/movieActions';
export interface IMovieState {
//property: any;
genres: any;
}
const initialMovieState: IMovieState = {
//property: null,genres: null,};
export const movieReducer: Reducer<IMovieState,MovieActions> = (
state = initialMovieState,action
) => {
switch (action.type) {
case MovieActionTypes.GENRE: {
console.log('MovieActionTypes.GENRE called')
return {
genres: action.genres,};
}
default:
console.log('Default action called')
return state;
}
};
src / store / store.ts:
import { applyMiddleware,combineReducers,createStore,Store } from 'redux';
import thunk from 'redux-thunk';
import { IMovieState,movieReducer } from '../reducers/movieReducer';
// Create an interface for the application state
export interface IAppState {
movieState: IMovieState
}
// Create the root reducer
const rootReducer = combineReducers<IAppState>({
movieState: movieReducer
});
// Create a configure store function of type `IAppState`
export default function configureStore(): Store<IAppState,any> {
const store = createStore(rootReducer,undefined,applyMiddleware(thunk));
return store;
}
src / components / MovieForm.tsx(应该分派动作的文件):
import React,{ useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Box from '@material-ui/core/Box';
import Select from '@material-ui/core/Select';
import MenuItem from '@material-ui/core/MenuItem';
import { spacing } from '@material-ui/system';
import Card from '@material-ui/core/Card';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import { CardHeader,TextField,CircularProgress } from '@material-ui/core';
import { useDispatch,useSelector } from 'react-redux';
import { movieAction } from '../actions/movieActions';
import { IAppState } from '../store/store';
import axios from 'axios';
const MovieForm = () => {
const dispatch = useDispatch()
const getGenres = () => {
console.log('actions dispatched')
dispatch(movieAction())
}
const genres = useSelector((state: IAppState) => state.movieState.genres);
//const [genreChoice,setGenreChoice] = useState('')
return (
<>
<h1>Movie Suggester</h1>
<Paper elevation={3}>
<Box p={10}>
<Card>
<div>Hello World. </div>
<Select onChange={() => console.log(genres)}>
<MenuItem>
hello
</MenuItem>
<br />
<br />
</Select>
<Button onClick={() => {
getGenres()
setTimeout(function(){
console.log(genres)
},5000)
}}>genres list</Button>
<Button onClick={() => console.log(axios.get(`https://api.themoviedb.org/3/discover/movie?api_key=${process.env.REACT_APP_MOVIE_API_KEY}&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&with_genres=35&page=1`))}>Click me</Button>
</Card>
</Box>
</Paper>
</>
)
}
export default MovieForm
这是src / index.tsx,以防问题出在我不知情的情况下:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'
import { BrowserRouter as Router } from 'react-router-dom';
import './index.css';
import CssBaseline from '@material-ui/core/CssBaseline';
import { ThemeProvider } from '@material-ui/core/styles';
import theme from './theme';
import App from './App';
import configureStore from './store/store';
const store = configureStore();
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<ThemeProvider theme={theme}>
{/* CssBaseline kickstart an elegant,consistent,and simple baseline to build upon. */}
<CssBaseline />
<Router>
<App />
</Router>
</ThemeProvider>
</Provider>
</React.StrictMode>,document.getElementById('root')
);
感谢您查看并尝试帮助我看看我无法做到的事情!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。