[英]Fetch API data with react and filter search input with autocomplete
I have a question regarding a React filter search input.我有一个关于 React 过滤器搜索输入的问题。
I have two Components the the moment.我现在有两个组件。
FirstPageComponent.js FirstPageComponent.js
import React from "react"
import AutoComplete from "./AutoComplete"
export class FirstPageComponent extends React.Component {
constructor() {
super()
this.state = {
rows: [],
loading: true,
}
}
async componentDidMount(searchTerm = "marvel") {
await fetch(
"https://api.themoviedb.org/3/search/movie?api_key=&query=" +
searchTerm
)
.then(response => response.json())
.then(responseData => {
this.setState({
rows: responseData.results,
loading: false,
})
})
.catch(error => {
console.log("Error fetching and parsing data", error)
})
}
render() {
console.log(this.state.rows)
return <AutoComplete movies={["hej"]} />
}
}
and和
AutoComplete.js自动完成.js
import React from "react"
export default class AutoComplete extends React.Component {
constructor(props) {
super(props)
this.state = {
rows: [],
loading: false,
userInput: "",
}
}
onChange = e => {
const { movies } = this.props
const userInput = e.currentTarget.value
const rows = movies.filter(
suggestion =>
suggestion.toLowerCase().indexOf(userInput.toLowerCase()) > -1
)
this.setState({
rows,
loading: true,
userInput: e.currentTarget.value,
})
}
onClick = e => {
this.setState({
rows: [],
loading: false,
userInput: e.currentTarget.innerText,
})
}
render() {
const {
onChange,
onClick,
state: { rows, loading, userInput },
} = this
let moviesListComponent
if (loading && userInput) {
if (rows.length) {
moviesListComponent = (
<ul>
{rows.map((movie, index) => {
return (
<li key={index} onClick={onClick}>
{movie}
</li>
)
})}
</ul>
)
} else {
moviesListComponent = (
<>
<p>Couldn't find any movies. Try searching for another movie.</p>
</>
)
}
}
return (
<React.Fragment>
<input type="search" onChange={onChange} value={userInput} />
{moviesListComponent}
</React.Fragment>
)
}
}
I basically want to know if i'm approaching this the right way.我基本上想知道我是否以正确的方式接近这个。 I want to make a dynamic request for movie titles from fetch(” https://themovie.db ”) API.
我想从 fetch(” https://themovie.db ”) API 动态请求电影标题。
Send down the movie titles as props and then filter the values in autocomplete component if the user input is similar to the movie title props.如果用户输入类似于电影标题道具,则将电影标题作为道具发送,然后过滤自动完成组件中的值。
Am i thinking about this the right way?我是否以正确的方式思考这个问题? I've tried to have the fetch call in the same component as AutoComplete but haven't gotten it to work as i want it to.
我试图在与 AutoComplete 相同的组件中进行 fetch 调用,但没有让它按我想要的方式工作。 How would you setup the component structure if you'd be solving this issue for example?
例如,如果您要解决此问题,您将如何设置组件结构?
Feel free to ask if there're any confusions.随意询问是否有任何混淆。
Thanks谢谢
These are my assumptions about the above code, let me know if any are incorrect.这些是我对上述代码的假设,如果有任何不正确,请告诉我。
AutoComplete
component.AutoComplete
组件动态过滤 API 请求返回的数据。 Most of your React code here looks pretty good, but I've got some recommendations:这里的大部分 React 代码看起来都不错,但我有一些建议:
MovieList
function component that simply takes an array of movie
objects, and a titleFilter
string and renders them.MovieList
function 组件,它只需要一个movie
对象数组和一个titleFilter
字符串并呈现它们。componentDidMount
doesn't take arguments. componentDidMount
不采用 arguments。 searchTerm
should be a prop of FirstPageComponent
(presumably set by the parent component by some kind of selection or user input) searchTerm
应该是FirstPageComponent
的一个 prop(可能是由父组件通过某种选择或用户输入设置的)AutoComplete
to TitleFilter
or the like.AutoComplete
重命名为TitleFilter
等。 It's not really auto-completing, it's more of a filter field.if (loading && userInput) {
will result in displaying no movies when the user hasn't yet filled in text into the filter field.if (loading && userInput) {
将导致当用户尚未在过滤器字段中填写文本时不显示电影。 I'm not sure that is what you would want.<p>Couldn't find any movies. Try searching for another movie.</p>
<p>Couldn't find any movies. Try searching for another movie.</p>
<p>Couldn't find any movies. Try searching for another movie.</p>
because you could have just filtered out all the results returned. <p>Couldn't find any movies. Try searching for another movie.</p>
因为您可能已经过滤掉了所有返回的结果。 In this case, it wasn't that you couldn't find movies, it's that your filter is too restrictive.onClick
handler, I'm not sure such a general approach is best.onClick
处理程序,我不确定这种通用方法是否最好。 It could create a strange interaction if you were to somehow click on the <ul>
, for example.<ul>
,它可能会产生奇怪的交互。 To improve this, I'd recommend each movie row component implement its own onClick
and call a function to set the filter.onClick
并调用 function 来设置过滤器。 Small nits:小尼特:
userInput: e.currentTarget.value,
could be shortened to userInput,
, which is shorthand for userInput: userInput,
(you already have a variable named userInput
.) userInput: e.currentTarget.value,
可以缩写为userInput,
,它是userInput: userInput,
的简写(你已经有一个名为userInput
的变量。)key
props, an actual unique id would be better, in the case you change your filtering and index numbers don't line up with the unique rows you're rendering anymore.key
道具,实际的唯一 id 会更好,以防您更改过滤并且索引号不再与您正在呈现的唯一行对齐。MovieRow
function component which takes a movie
object and renders it.MovieRow
function 组件,它需要一个movie
object 并渲染它。 It just keeps the code a bit cleaner.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.