В этом приложении я попытаюсь объяснить, как реализовать живой поиск в реагирующем приложении с помощью Rick & Morty Api.
- Создайте React-приложение:
$ npx create-react-app app-name
- Установка интерфейса Axios и материалов
$ npm i -save axios @material-ui/core
После очистки приложения от заданных по умолчанию страниц вы должны начать создавать свой первый компонент, в этом случае мы начнем создавать компонент навигационной панели.
Сначала создайте папку и назовите ее компоненты в папке src.
затем создайте новый файл и назовите его Appbar.js, это будет наш компонент панели навигации.
скопируйте и вставьте приведенный ниже код, и теперь ваш компонент готов к использованию в вашем приложении.
import React from 'react'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; import Typography from '@material-ui/core/Typography'; import InputBase from '@material-ui/core/InputBase'; import { fade, makeStyles } from '@material-ui/core/styles'; import SearchIcon from '@material-ui/icons/Search'; import IconButton from '@material-ui/core/IconButton'; import MenuIcon from '@material-ui/icons/Menu' const useStyles = makeStyles((theme) => ({ root: { flexGrow: 1, paddingBottom : 20, }, 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), 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(props) { const classes = useStyles(); return ( <div className={classes.root}> <AppBar position="static" style={{ background: '#61DBA0' }}> <Toolbar> <IconButton className={classes.menuButton}> <MenuIcon/> </IconButton> <Typography className={classes.title} variant="h6" noWrap> Your Titles </Typography> <div className={classes.search}> <div className={classes.searchIcon}> <SearchIcon /> </div> <InputBase placeholder="Search…" classes={{ root: classes.inputRoot, input: classes.inputInput, }} inputProps={{ 'aria-label': 'search' }} /> </div> </Toolbar> </AppBar> </div> ); }
Теперь мы должны создать еще один компонент с именем Childcomponent , в папке вашего компонента создайте файл с именем Childcomponent.js.
Скопируйте и вставьте приведенный ниже код, чтобы теперь ваш компонент был готов к использованию.
import React from 'react'; import { makeStyles,withStyles } from '@material-ui/core/styles'; import Card from '@material-ui/core/Card'; import Grid from '@material-ui/core/Grid'; import Badge from '@material-ui/core/Badge'; import CardHeader from '@material-ui/core/CardHeader'; import CardMedia from '@material-ui/core/CardMedia'; import CardContent from '@material-ui/core/CardContent'; import Avatar from '@material-ui/core/Avatar'; import Typography from '@material-ui/core/Typography'; export default function Childcomponent (props) { const StyledBadge = withStyles((theme) => ({ badge: { backgroundColor: props.status === "Alive" ? "#5cb85c" : "#d9534f", boxShadow: "0 0 0 3px #fff" }, }))(Badge); const useStyles = makeStyles((theme) => ({ root: { }, media: { height: 0, paddingTop: '56.25%', }, title : { textAlign : 'left' }, avatar: { backgroundColor: "#0275d8", }, })); const classes = useStyles(); return ( <Grid item md={3} xs={12} sm={6}> <Card className={classes.root}> <CardHeader avatar={ <StyledBadge overlap="circle" anchorOrigin={{ vertical: 'bottom', horizontal: 'right', }} variant="dot" > <Avatar alt="Remy Sharp">{props.name.charAt(0)}</Avatar> </StyledBadge> } title={props.name} className={classes.title} /> <CardMedia className={classes.media} image={props.image} title="Paella dish" /> <CardContent> <Typography variant="caption" display="block" gutterBottom className={classes.title}> Species : {props.species} </Typography> <Typography variant="caption" display="block" gutterBottom className={classes.title}> Gender : {props.gender} </Typography> <Typography variant="caption" display="block" gutterBottom className={classes.title}> Origin : {props.origin} </Typography> </CardContent> </Card> </Grid> ); }
Третий компонент необходим для разбиения на страницы, как обычно, в папке компонентов создайте новый файл с именем Stepper.js, скопируйте и вставьте приведенный ниже код.
import React from 'react'; import { makeStyles, useTheme } from '@material-ui/core/styles'; import MobileStepper from '@material-ui/core/MobileStepper'; import Button from '@material-ui/core/Button'; import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft'; import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight'; const useStyles = makeStyles({ root: { flexGrow: 1, marginBottom : 20, }, }); export default function Stepper(props) { const classes = useStyles(); const theme = useTheme(); return ( <MobileStepper position="static" className={classes.root} steps={1} nextButton={ <Button size="small" onClick={props.next} disabled={props.isNext === null}> Next {theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />} </Button> } backButton={ <Button size="small" onClick={props.prev} disabled={props.isPrev === null}> {theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />} Back </Button> } /> ); }
Теперь нам нужно создать наш основной компонент, чтобы мы могли построить нашу страницу. в той же папке создайте новый файл с именем Mycomponent.js, куда мы импортируем все предыдущие компоненты, которые мы уже создали.
import React from 'react' import Grid from '@material-ui/core/Grid' import Childcomponent from './Childcomponent' import Appbar from './Appbar' import axios from 'axios' import Container from '@material-ui/core/Container' import Stepper from './Stepper' export default class Mycomponent extends React.Component { constructor (props) { super (props) this.state = { items : [], api_URL : 'https://rickandmortyapi.com/api/character/?name=', nextPage : '', prevPage : '', isLoaded : false, query : '' } } fetchDataFromApi (url,query) { axios.get(url+query) .then(res => { this.setState({ items : res.data.results, nextPageLink : res.data.info.next, prevPageLink : res.data.info.prev, isLoaded : true }) }).catch (err => { console.log(err) }) } componentDidMount() { this.fetchDataFromApi(this.state.api_URL,this.state.query); } handleOnInputChange = (event) => { this.setState({ query : event.target.value, isLoaded : false }, () => { this.fetchDataFromApi(this.state.api_URL,this.state.query) }) } nextPage = () => { this.fetchDataFromApi(this.state.nextPageLink,'') } prevPage = () => { this.fetchDataFromApi(this.state.prevPageLink,'') } render() { var {items,nextPageLink, prevPageLink} = this.state return ( <Container spacing={3}> <Grid item md={12} xs={12}> <Appbar search={this.handleOnInputChange}></Appbar> </Grid> <Grid item md={12}> <Stepper isNext={nextPageLink} isPrev={prevPageLink} next={this.nextPage} prev={this.prevPage} style={{justifyContent: 'flex-end'}} /> </Grid> <Grid item container spacing={2}> { items.map (item => <Childcomponent key={item.id} name={item.name} status ={item.status} species={item.species} image={item.image} gender={item.gender} origin={item.origin.name} ></Childcomponent>)} </Grid> <Grid item md={12}> <Stepper isNext={nextPageLink} isPrev={prevPageLink} next={this.nextPage} prev={this.prevPage} style={{justifyContent: 'flex-end'}} /> </Grid> </Container> ); } }
этот компонент имеет другую функцию, чтобы сделать живой поиск API.
чтобы запустить приложение, перейдите в файл App.js, импортируйте основной компонент, ваш App.js должен выглядеть так.
import React from 'react'; import './App.css'; import Mycomponent from './components/Mycomponent' function App() { return ( <div className="App"> <Mycomponent/> </div> ); } export default App;
если вы хотите проверить, работает ли это в вашей командной строке, введите: npm run start.
теперь у вас должно получиться что-то вроде этого:
Наслаждаться ! основные функции API живого поиска находятся в Mycomponent.js.
Репозиторий GitHub: https://github.com/benharrimohamed/Rick-and-morty
Предварительное приложение: https://benharrimohamed.github.io/Rick-and-morty/