我想使用 react hook 'useState' 来保存从 API 获取的信息并显示在 scrren 上。但是,我不能在 class 中使用,所以我该怎么办?
I want to use react hook 'useState' to save the information fetched from API and show on the scrren. But, I can't use in class so what can I do?
因此,在某些情况下,我会在单击搜索按钮时获取一些搜索结果。完美点击搜索按钮后,结果显示在 console.log()
中。 SearchComponent.js
在下方。
import React, { Component, useState } from 'react'
import { API_KEY, API_URL } from '../config/keys';
import { Link } from 'react-router-dom';
class SearchBox extends Component {
constructor(props) {
super(props);
this.state = {
searchQuery: ""
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.onChangeValue = this.onChangeValue.bind(this);
}
handleChange = (e) => {
e.preventDefault();
const { name, value } = e.target;
this.setState({ [name]: value });
}
handleSubmit = (e) => {
e.preventDefault();
var data = this.state.searchQuery;
const url = `${API_URL}search/${this.state.selectedOption}?api_key=${API_KEY}&language=en-US&query=${encodeURI(data)}&page=1&include_adult=false`;
fetch(url)
.then(response => response.json())
.then(response => {
console.log(response);
const result = response.results;
})
}
onChangeValue(event) {
this.setState({
selectedOption: event.target.value
});
}
render() {
return (
<>
<div className="mt-3">
{/* Breadcrumb */}
<div style={{ width: '95%', margin: '1rem auto' }}>
<nav aria-label="breadcrumb">
<ol className="breadcrumb">
<li className="breadcrumb-item"><Link to='/'>Home</Link></li>
<li className="breadcrumb-item active" aria-current="page">Search</li>
</ol>
</nav>
</div>
<div className="row">
<div className="col-6 offset-3">
<form className="form-group">
<div className="input-group">
<input
className="form-control"
type="text"
placeholder= 'Search...'
onChange={this.handleChange}
name= 'searchQuery'
value={this.state.searchQuery} />
<button onClick={this.handleSubmit} type="submit" className="btn btn-primary input-group-addon" ><span className="fa fa-search fa-lg"></span></button>
</div>
{/* radio buttons */}
<div className="mt-2">
<div class="form-check">
<input
class="form-check-input"
type="radio"
name="movie"
value="movie"
checked={this.state.selectedOption === "movie"}
onChange={this.onChangeValue}
/>
<span class="form-check-label font-weight-bold">
Movies
</span>
</div>
<div class="form-check">
<input
class="form-check-input"
type="radio"
value="tv"
name="tvshow"
checked={this.state.selectedOption === "tv"}
onChange={this.onChangeValue}
/>
<span class="form-check-label font-weight-bold">
TV Shows
</span>
</div>
</div>
</form>
</div>
</div>
</div>
{/* search results */}
<div style={{ width: '95%', margin: '1rem auto' }}>
<div className="text-center">
<div className="font-weight-lighter h2"> Search Results </div>
</div>
</div>
</>
)
}
}
export default SearchBox;
结果数组在handleSubmit()
的result
变量中。我如何使用 useState 来存储我的 result
var 然后在 scrren.
上显示它
如果您不明白我在谈论如何使用这个挂钩,我已经附上了一个做类似事情的文件。
landingComponent.js
import React, { useEffect, useState } from 'react';
import {API_URL, API_KEY, IMAGE_URL} from '../../config/keys';
import { Row } from 'reactstrap';
import MainImage from './MainImage';
import GridCard from './GridCard';
import { Link } from 'react-router-dom';
function LandingPage() {
const [Movies, setMovies] = useState([]);
const [CurrentPage, setCurrentPage] = useState(0);
useEffect( () => {
const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=en-US&page=1`;
fetchMovies(endpoint);
}, []);
const fetchMovies = (path) => {
fetch(path)
.then(response => response.json())
.then(response => {
console.log(response);
setMovies([...Movies, ...response.results]);
setCurrentPage(response.page);
})
}
const handleClick = () => {
const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=en-US&page=${CurrentPage + 1}`
fetchMovies(endpoint);
}
return (
<div style={{ width: '100%', margin: 0 }} >
<div style={{ width: '95%', margin: '1rem auto' }}>
{/* Breadcrumbs */}
<nav aria-label="breadcrumb">
<ol className="breadcrumb">
<li className="breadcrumb-item"><Link to='/'>Home</Link></li>
<li className="breadcrumb-item active" aria-current="page">Movies</li>
</ol>
</nav>
<div className="font-weight-bold h2"> Latest Movies </div>
<hr style={{borderColor:'black'}}/>
<Row>
{Movies && Movies.map((movie, index) => (
<React.Fragment key={index}>
<GridCard
image={movie.poster_path && `${IMAGE_URL}w500${movie.poster_path}`}
movieId={movie.id} movieTitle={movie.title} name={movie.original_title}
/>
</React.Fragment>
))}
</Row>
<br />
<div className="text-center">
<button className="btn btn-primary" onClick={handleClick}> Load More </button>
</div>
</div>
</div>
)
}
export default LandingPage
我想在 SearchComponent.js
中使用相同的方法。我尝试了很多东西,但 none 奏效了。感谢帮助。
React 有两种使用组件的方式:
Class 个组件
这样声明:class ComponentName extends Component {
然后您的状态使用以下方式进行管理:this.setState()
函数组件
与第二个示例一样声明为函数
在那里你可以使用钩子和 useState()
因此,如果您不打算重写所有组件,则必须使用 this.setState()
当您获取数据时,您需要再次将其存储在状态中,从而在状态中创建 results:[]
属性。
handleSubmit = (e) => {
e.preventDefault();
var data = this.state.searchQuery;
const url = `${API_URL}search/${this.state.selectedOption}?api_key=${API_KEY}&language=en-US&query=${encodeURI(data)}&page=1&include_adult=false`;
fetch(url)
.then(response => response.json())
.then(response => {
console.log(response);
const result = response.results;
this.setState({results:result}); //Here you store the state.
});
}
现在您必须在 results JSX block
中显示它。
{/* search results */}
<div style={{ width: '95%', margin: '1rem auto' }}>
<div className="text-center">
<div className="font-weight-lighter h2"> Search Results </div>
<div className="results">
<ul>
{this.state.results.length && this.state.results.map(item => { return (
<li> {item} </li>
) })}
</ul>
</div>
</div>
</div>
因此,在某些情况下,我会在单击搜索按钮时获取一些搜索结果。完美点击搜索按钮后,结果显示在 console.log()
中。 SearchComponent.js
在下方。
import React, { Component, useState } from 'react'
import { API_KEY, API_URL } from '../config/keys';
import { Link } from 'react-router-dom';
class SearchBox extends Component {
constructor(props) {
super(props);
this.state = {
searchQuery: ""
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.onChangeValue = this.onChangeValue.bind(this);
}
handleChange = (e) => {
e.preventDefault();
const { name, value } = e.target;
this.setState({ [name]: value });
}
handleSubmit = (e) => {
e.preventDefault();
var data = this.state.searchQuery;
const url = `${API_URL}search/${this.state.selectedOption}?api_key=${API_KEY}&language=en-US&query=${encodeURI(data)}&page=1&include_adult=false`;
fetch(url)
.then(response => response.json())
.then(response => {
console.log(response);
const result = response.results;
})
}
onChangeValue(event) {
this.setState({
selectedOption: event.target.value
});
}
render() {
return (
<>
<div className="mt-3">
{/* Breadcrumb */}
<div style={{ width: '95%', margin: '1rem auto' }}>
<nav aria-label="breadcrumb">
<ol className="breadcrumb">
<li className="breadcrumb-item"><Link to='/'>Home</Link></li>
<li className="breadcrumb-item active" aria-current="page">Search</li>
</ol>
</nav>
</div>
<div className="row">
<div className="col-6 offset-3">
<form className="form-group">
<div className="input-group">
<input
className="form-control"
type="text"
placeholder= 'Search...'
onChange={this.handleChange}
name= 'searchQuery'
value={this.state.searchQuery} />
<button onClick={this.handleSubmit} type="submit" className="btn btn-primary input-group-addon" ><span className="fa fa-search fa-lg"></span></button>
</div>
{/* radio buttons */}
<div className="mt-2">
<div class="form-check">
<input
class="form-check-input"
type="radio"
name="movie"
value="movie"
checked={this.state.selectedOption === "movie"}
onChange={this.onChangeValue}
/>
<span class="form-check-label font-weight-bold">
Movies
</span>
</div>
<div class="form-check">
<input
class="form-check-input"
type="radio"
value="tv"
name="tvshow"
checked={this.state.selectedOption === "tv"}
onChange={this.onChangeValue}
/>
<span class="form-check-label font-weight-bold">
TV Shows
</span>
</div>
</div>
</form>
</div>
</div>
</div>
{/* search results */}
<div style={{ width: '95%', margin: '1rem auto' }}>
<div className="text-center">
<div className="font-weight-lighter h2"> Search Results </div>
</div>
</div>
</>
)
}
}
export default SearchBox;
结果数组在handleSubmit()
的result
变量中。我如何使用 useState 来存储我的 result
var 然后在 scrren.
如果您不明白我在谈论如何使用这个挂钩,我已经附上了一个做类似事情的文件。
landingComponent.js
import React, { useEffect, useState } from 'react';
import {API_URL, API_KEY, IMAGE_URL} from '../../config/keys';
import { Row } from 'reactstrap';
import MainImage from './MainImage';
import GridCard from './GridCard';
import { Link } from 'react-router-dom';
function LandingPage() {
const [Movies, setMovies] = useState([]);
const [CurrentPage, setCurrentPage] = useState(0);
useEffect( () => {
const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=en-US&page=1`;
fetchMovies(endpoint);
}, []);
const fetchMovies = (path) => {
fetch(path)
.then(response => response.json())
.then(response => {
console.log(response);
setMovies([...Movies, ...response.results]);
setCurrentPage(response.page);
})
}
const handleClick = () => {
const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=en-US&page=${CurrentPage + 1}`
fetchMovies(endpoint);
}
return (
<div style={{ width: '100%', margin: 0 }} >
<div style={{ width: '95%', margin: '1rem auto' }}>
{/* Breadcrumbs */}
<nav aria-label="breadcrumb">
<ol className="breadcrumb">
<li className="breadcrumb-item"><Link to='/'>Home</Link></li>
<li className="breadcrumb-item active" aria-current="page">Movies</li>
</ol>
</nav>
<div className="font-weight-bold h2"> Latest Movies </div>
<hr style={{borderColor:'black'}}/>
<Row>
{Movies && Movies.map((movie, index) => (
<React.Fragment key={index}>
<GridCard
image={movie.poster_path && `${IMAGE_URL}w500${movie.poster_path}`}
movieId={movie.id} movieTitle={movie.title} name={movie.original_title}
/>
</React.Fragment>
))}
</Row>
<br />
<div className="text-center">
<button className="btn btn-primary" onClick={handleClick}> Load More </button>
</div>
</div>
</div>
)
}
export default LandingPage
我想在 SearchComponent.js
中使用相同的方法。我尝试了很多东西,但 none 奏效了。感谢帮助。
React 有两种使用组件的方式:
Class 个组件
这样声明:class ComponentName extends Component {
然后您的状态使用以下方式进行管理:this.setState()
函数组件
与第二个示例一样声明为函数
在那里你可以使用钩子和 useState()
因此,如果您不打算重写所有组件,则必须使用 this.setState()
当您获取数据时,您需要再次将其存储在状态中,从而在状态中创建 results:[]
属性。
handleSubmit = (e) => {
e.preventDefault();
var data = this.state.searchQuery;
const url = `${API_URL}search/${this.state.selectedOption}?api_key=${API_KEY}&language=en-US&query=${encodeURI(data)}&page=1&include_adult=false`;
fetch(url)
.then(response => response.json())
.then(response => {
console.log(response);
const result = response.results;
this.setState({results:result}); //Here you store the state.
});
}
现在您必须在 results JSX block
中显示它。
{/* search results */}
<div style={{ width: '95%', margin: '1rem auto' }}>
<div className="text-center">
<div className="font-weight-lighter h2"> Search Results </div>
<div className="results">
<ul>
{this.state.results.length && this.state.results.map(item => { return (
<li> {item} </li>
) })}
</ul>
</div>
</div>
</div>