如何在Material UI中向SearchAppBar添加搜索功能?

时间:2020-07-12 10:08:50

标签: javascript reactjs material-ui react-hooks fetch-api

因此,我有一个基本的react应用,允许用户从Movie Database API搜索和显示电影。

出现问题:我想将自定义的React Function SearchMovies()链接到材质ui组件,特别是材质Ui SearchAppBar。但是,我在将此功能添加到Material Ui SearchAppBar时遇到问题。

首先,我的自定义代码具有SearchMovies()函数。代码如下:

import React, { useState } from "react";
import MovieCard from "./movieCard";

export default function SearchMovies() {
  //states = input query, movies
  const [query, setQuery] = useState("");
  const [movies, setMovies] = useState([]);

  const searchMovies = async (e) => {
    e.preventDefault();

    const url = `https://api.themoviedb.org/3/search/movie?api_key=a2657ca16cc801deb9a65e9f7f9e3d4f&language=en-US&query=${query}&page=1&include_adult=false`;
    try {
      const res = await fetch(url);
      const data = await res.json();
      //console.log(data.results);
      setMovies(data.results);
    } catch (err) {
      console.error(err);
    }
  };

  return (
    <>
      <form className="form" onSubmit={searchMovies}>
        <label className="label" htmlFor="query">
          Movie Name
        </label>

        <input
          type="text"
          className="input"
          name="query"
          placeholder="i.e. Star Wars"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
        />

        <button className="button" type="Submit">
          Search
        </button>
      </form>
      <div className="card-list">
        {movies
          .filter((movie) => movie.poster_path)
          .map((movie) => (
            <MovieCard movie={movie} key={movie.id} />
          ))}
      </div>
    </>
  );
}

第二,这是Material UI SearchAppBar的代码:

import React from "react";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import IconButton from "@material-ui/core/IconButton";
import Typography from "@material-ui/core/Typography";
import InputBase from "@material-ui/core/InputBase";
import { fade, makeStyles } from "@material-ui/core/styles";
import MenuIcon from "@material-ui/icons/Menu";
import SearchIcon from "@material-ui/icons/Search";
import searchMovies from "./searchMovies";

const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
  },
  menuButton: {
    marginRight: theme.spacing(2),
  },
  title: {
    flexGrow: 1,
    display: "none",
    [theme.breakpoints.up("sm")]: {
      display: "block",
    },
  },
  search: {
    position: "relative",
    borderRadius: theme.shape.borderRadius,
    backgroundColor: fade(theme.palette.common.white, 0.15),
    "&:hover": {
      backgroundColor: fade(theme.palette.common.white, 0.25),
    },
    marginLeft: 0,
    width: "100%",
    [theme.breakpoints.up("sm")]: {
      marginLeft: theme.spacing(1),
      width: "auto",
    },
  },
  searchIcon: {
    padding: theme.spacing(0, 2),
    height: "100%",
    position: "absolute",
    pointerEvents: "none",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
  },
  inputRoot: {
    color: "inherit",
  },
  inputInput: {
    padding: theme.spacing(1, 1, 1, 0),
    // vertical padding + font size from searchIcon
    paddingLeft: `calc(1em + ${theme.spacing(4)}px)`,
    transition: theme.transitions.create("width"),
    width: "100%",
    [theme.breakpoints.up("sm")]: {
      width: "12ch",
      "&:focus": {
        width: "20ch",
      },
    },
  },
}));

export default function SearchAppBar() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <AppBar position="static">
        <Toolbar>
          <IconButton
            edge="start"
            className={classes.menuButton}
            color="inherit"
            aria-label="open drawer"
          >
            <MenuIcon />
          </IconButton>
          <Typography className={classes.title} variant="h5" noWrap>
            MovieZone
          </Typography>
          <div className={classes.search}>
            <div className={classes.searchIcon}>
              <SearchIcon />
            </div>
            <InputBase
              //value={query}
              //onChange={(e) => setQuery(e.target.value)}
              onSubmit={searchMovies}
              placeholder="Search…"
              classes={{
                root: classes.inputRoot,
                input: classes.inputInput,
              }}
              inputProps={{ "aria-label": "search" }}
            />
          </div>
        </Toolbar>
      </AppBar>
    </div>
  );
}

那么我如何将SearchMovies()函数注入到Material UI SearchAppBar中,以便用户可以使用Material UI组件来调用SearchMovies()函数并显示电影结果?

1 个答案:

答案 0 :(得分:0)

您可以从有角度的材质表示例中获取参考,但是您可以使用毡垫卡来过滤dataSource所提供的内容并调用该方法,或者只是通过构造过滤器arraylist或再次提供给您的东西来更改arrayList UI组件

这是链接

https://stackblitz.com/angular/kgboooaejyn?embed=1&file=src/app/table-filtering-example.ts

您需要专注于此功能

applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    this.dataSource.filter = filterValue.trim().toLowerCase();
  }

这里没有数据源,但是您可以过滤ArrayList中的内容

希望这个想法行得通... !!