React 是一个非常流行的前端框架,它可以帮助我们快速构建复杂的单页面应用(SPA)。在本文中,我们将介绍如何使用 React 全家桶开发一个实际的 SPA 单页面应用。
什么是 React 全家桶?
React 全家桶通常指的是 React、React Router 和 Redux。React 是一个用于构建用户界面的 JavaScript 库,React Router 是一个用于管理应用程序路由的库,Redux 是一个用于管理应用程序状态的库。
React 全家桶通常被用于构建复杂的单页面应用程序,因为它们提供了一个完整的解决方案,可以帮助我们管理应用程序的状态和路由,并将应用程序的各个部分组合在一起。
项目概述
在本文中,我们将开发一个简单的 SPA 应用程序,该应用程序允许用户查看电影列表并搜索电影。我们将使用 React、React Router 和 Redux 来构建应用程序。
在应用程序中,我们将使用一个公共 API 来获取电影数据。我们还将使用 React Router 来管理我们应用程序的路由,并使用 Redux 来管理我们应用程序的状态。
项目结构
在开始开发之前,让我们先了解一下项目的结构。我们的项目将包含以下文件和目录:
// www.javascriptcn.com code example
- src/
- actions/
- index.js
- components/
- Movie.js
- MovieList.js
- SearchBar.js
- containers/
- App.js
- reducers/
- index.js
- movies.js
- App.css
- App.js
- index.jssrc/actions/目录包含 Redux action creators。src/components/目录包含 React 组件。src/containers/目录包含连接到 Redux store 的 React 容器组件。src/reducers/目录包含 Redux reducers。src/App.css文件包含应用程序的样式。src/App.js文件包含应用程序的主要 React 组件。src/index.js文件是应用程序的入口点。
开发步骤
1. 安装依赖
我们首先需要安装一些依赖项,包括 React、React Router 和 Redux。我们还需要安装一些用于构建应用程序的工具,包括 Webpack 和 Babel。
npm install react react-dom react-router-dom redux react-redux redux-thunk axios npm install -D webpack webpack-cli webpack-dev-server babel-loader @babel/core @babel/preset-env @babel/preset-react
2. 创建基本的应用程序结构
我们将创建一个基本的应用程序结构,包括一个 App.js 组件和一个 index.js 入口文件。在 App.js 文件中,我们将创建一个简单的 React 组件,该组件将显示一个搜索栏和电影列表。
// www.javascriptcn.com code example
import React from 'react';
import SearchBar from './components/SearchBar';
import MovieList from './components/MovieList';
function App() {
return (
<div className="App">
<SearchBar />
<MovieList />
</div>
);
}
export default App;在 index.js 文件中,我们将渲染 App 组件并将其呈现在页面上。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));3. 创建 Redux store 和 reducers
我们将创建一个 Redux store 和 reducers,以管理我们应用程序的状态。我们将在 reducers/movies.js 文件中创建一个 movies reducer,该 reducer 将处理与电影列表相关的所有操作。
// www.javascriptcn.com code example
const initialState = {
movies: [],
loading: false,
error: null,
};
function moviesReducer(state = initialState, action) {
switch (action.type) {
case 'FETCH_MOVIES_REQUEST':
return {
...state,
loading: true,
error: null,
};
case 'FETCH_MOVIES_SUCCESS':
return {
...state,
loading: false,
movies: action.payload,
};
case 'FETCH_MOVIES_FAILURE':
return {
...state,
loading: false,
error: action.payload,
};
default:
return state;
}
}
export default moviesReducer;我们还需要在 reducers/index.js 文件中将 movies reducer 组合在一起。
import { combineReducers } from 'redux';
import moviesReducer from './movies';
const rootReducer = combineReducers({
movies: moviesReducer,
});
export default rootReducer;最后,我们将创建一个 Redux store,并将其传递给我们的应用程序。
// www.javascriptcn.com code example
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
import App from './App';
const store = createStore(rootReducer, applyMiddleware(thunk));
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);4. 创建 Redux action creators 和异步操作
我们将创建 Redux action creators 来处理电影列表的异步操作。我们将在 actions/index.js 文件中创建一个 fetchMovies action creator,该 action creator 将使用 Axios 库从 API 中获取电影列表。
// www.javascriptcn.com code example
import axios from 'axios';
function fetchMoviesRequest() {
return {
type: 'FETCH_MOVIES_REQUEST',
};
}
function fetchMoviesSuccess(movies) {
return {
type: 'FETCH_MOVIES_SUCCESS',
payload: movies,
};
}
function fetchMoviesFailure(error) {
return {
type: 'FETCH_MOVIES_FAILURE',
payload: error,
};
}
export function fetchMovies(searchTerm) {
return async (dispatch) => {
dispatch(fetchMoviesRequest());
try {
const response = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=${process.env.REACT_APP_MOVIE_API_KEY}&query=${searchTerm}`
);
dispatch(fetchMoviesSuccess(response.data.results));
} catch (error) {
dispatch(fetchMoviesFailure(error.message));
}
};
}我们还需要在 MovieList 组件中使用 connect 函数连接到 Redux store 并调用 fetchMovies action creator。
// www.javascriptcn.com code example
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
import { fetchMovies } from '../actions';
import Movie from './Movie';
function MovieList({ movies, loading, error, fetchMovies }) {
useEffect(() => {
fetchMovies('Star Wars');
}, [fetchMovies]);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
return (
<div>
{movies.map((movie) => (
<Movie key={movie.id} movie={movie} />
))}
</div>
);
}
function mapStateToProps(state) {
return {
movies: state.movies.movies,
loading: state.movies.loading,
error: state.movies.error,
};
}
export default connect(mapStateToProps, { fetchMovies })(MovieList);5. 创建路由
我们将使用 React Router 来创建应用程序的路由。我们将在 App.js 文件中创建一个 Router 组件,并将 MovieList 组件作为默认路由。
// www.javascriptcn.com code example
import React from 'react';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import SearchBar from './components/SearchBar';
import MovieList from './containers/MovieList';
function App() {
return (
<Router>
<div className="App">
<SearchBar />
<Switch>
<Route exact path="/" component={MovieList} />
</Switch>
</div>
</Router>
);
}
export default App;6. 创建搜索栏
最后,我们将创建一个搜索栏组件,该组件允许用户搜索电影。我们将在 SearchBar 组件中创建一个表单,并在表单提交时调用 fetchMovies action creator。
// www.javascriptcn.com code example
import React, { useState } from 'react';
import { connect } from 'react-redux';
import { fetchMovies } from '../actions';
function SearchBar({ fetchMovies }) {
const [searchTerm, setSearchTerm] = useState('');
function handleSubmit(event) {
event.preventDefault();
fetchMovies(searchTerm);
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Search for a movie..."
value={searchTerm}
onChange={(event) => setSearchTerm(event.target.value)}
/>
<button type="submit">Search</button>
</form>
);
}
export default connect(null, { fetchMovies })(SearchBar);完成应用程序
现在,我们已经完成了一个简单的 SPA 应用程序,该应用程序允许用户搜索电影并显示电影列表。我们使用了 React、React Router 和 Redux 来构建应用程序,并使用了 Axios 库来从 API 中获取电影数据。
完整的代码可以在 GitHub 上找到。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67da4645a941bf7134225fed