我正在使用 moviedb api 实现电影搜索功能。我只在 React 中实现,但我想在 Redux 中实现。这是我在 React 中的方法。
页眉.js
import React, { Component } from "react"
import { Navbar, Form, FormControl } from "react-bootstrap"
import { NavLink } from "react-router-dom"
import axios from "axios"
import MovieCards from "./MovieCards"
const apiKey = process.env.REACT_APP_MOVIE_DB_API_KEY
class Header extends Component {
state = {
isSearching: false,
value: "",
movies: []
}
searchMovies = async val => {
this.setState({ isSearching: true })
const res = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&language=en-US&query=${val}&page=1&include_adult=true`
)
const movies = await res.data.results
this.setState({ movies: movies, isSearching: false })
}
handleChange = e => {
const { name, value } = e.target
this.searchMovies(value)
this.setState({
[name]: value
})
}
render() {
return this.state.value === "" ? (
<div>
<Navbar
bg="dark"
expand="lg"
style={{ justifyContent: "space-around" }}
>
<NavLink to="/">
<Navbar.Brand>Movie Catalogue</Navbar.Brand>
</NavLink>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Form inline>
<FormControl
type="text"
placeholder="Search"
className="mr-sm-2"
onChange={this.handleChange}
name="value"
value={this.state.value}
/>
</Form>
</Navbar.Collapse>
<NavLink to="/popular">Popular</NavLink>
<NavLink to="/now-playing">Now Playing</NavLink>
<NavLink to="/top-rated">Top Rated</NavLink>
<NavLink to="/upcoming">Upcoming</NavLink>
</Navbar>
{this.state.movies.map((movie, i) => {
return <MovieCards key={i} movie={movie} />
})}
</div>
) : (
<div>
<Navbar
bg="dark"
expand="lg"
style={{ justifyContent: "space-around" }}
>
<NavLink to="/">
<Navbar.Brand>Movie Catalogue</Navbar.Brand>
</NavLink>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Form inline>
<FormControl
type="text"
placeholder="Search"
className="mr-sm-2"
onChange={this.handleChange}
name="value"
value={this.state.value}
/>
</Form>
</Navbar.Collapse>
<p style={{ color: "white" }}>
Search results for " {this.state.value} "
</p>
</Navbar>
{this.state.movies.map((movie, i) => {
return <MovieCards key={i} movie={movie} />
})}
</div>
)
}
}
export default Header
我想用 Redux 来做,所以我是这样做的。
页眉.js
import React, { Component } from "react"
import { Navbar, Form, FormControl } from "react-bootstrap"
import { NavLink } from "react-router-dom"
import axios from "axios"
import { connect } from "react-redux"
import { movieSearch } from "../actions/index"
import MovieCards from "./MovieCards"
const apiKey = process.env.REACT_APP_MOVIE_DB_API_KEY
class Header extends Component {
handleChange = e => {
const { name, value } = e.target
this.props.dispatch(movieSearch(value)) // I'm not sure if this is the right approach. I'm dispatching and then setting state.
this.setState({
[name]: value
})
}
render() {
return this.state.value === "" ? (
<div>
<Navbar
bg="dark"
expand="lg"
style={{ justifyContent: "space-around" }}
>
<NavLink to="/">
<Navbar.Brand>Movie Catalogue</Navbar.Brand>
</NavLink>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Form inline>
<FormControl
type="text"
placeholder="Search"
className="mr-sm-2"
onChange={this.handleChange}
name="value"
value={this.state.value}
/>
</Form>
</Navbar.Collapse>
<NavLink to="/popular">Popular</NavLink>
<NavLink to="/now-playing">Now Playing</NavLink>
<NavLink to="/top-rated">Top Rated</NavLink>
<NavLink to="/upcoming">Upcoming</NavLink>
</Navbar>
{this.state.movies.map((movie, i) => {
return <MovieCards key={i} movie={movie} />
})}
</div>
) : (
<div>
<Navbar
bg="dark"
expand="lg"
style={{ justifyContent: "space-around" }}
>
<NavLink to="/">
<Navbar.Brand>Movie Catalogue</Navbar.Brand>
</NavLink>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Form inline>
<FormControl
type="text"
placeholder="Search"
className="mr-sm-2"
onChange={this.handleChange}
name="value"
value={this.state.value}
/>
</Form>
</Navbar.Collapse>
<p style={{ color: "white" }}>
Search results for " {this.state.value} "
</p>
</Navbar>
{this.state.movies.map((movie, i) => {
return <MovieCards key={i} movie={movie} />
})}
</div>
)
}
}
const mapStateToProps = (state) => {
return state
}
export default connect(mapStateToProps)(Header)
动作/index.js
export const movieSearch = val => {
const movieSearchUrl = `https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&language=en-US&query=${val}&page=1&include_adult=true`
return async dispatch => {
dispatch({ type: "SEARCHING_MOVIES_START" })
try {
const res = await axios.get(movieSearchUrl)
dispatch({
type: "SEARCHING_MOVIES_SUCCESS",
data: { searchResults: res.data.results }
})
} catch (err) {
dispatch({
type: "SEARCHING_MOVIES_FAILURE",
data: { error: "Could not find the movie" }
})
}
}
}
减速器/movieSearchReducer.js
const initialState = {
value: "",
isSearchingMovies: false,
isSearchedMovies: false,
movieList: [],
searchingError: null
}
export const movieSearchReducer = (state = initialState, action) => {
switch (action.type) {
case "SEARCHING_MOVIES_START":
return {
...state,
isSearchingMovies: true,
searchingError: null
}
case "SEARCHING_MOVIES_SUCCESS":
return {
...state,
isSearchingMovies: false,
isSearchedMovies: true,
movieList: action.data,
searchingError: null
}
case "SEARCHING_MOVIES_FAILURE":
return {
...state,
searchingError: action.data.error
}
}
}
我不确定如何在 Redux 中实现以下输入表单部分。如果可以的话请帮忙。
onChange={this.handleChange}
name="value"
value={this.state.value}