简体   繁体   English

如何在同一页面上呈现不同的组件

[英]how to render different component on the same page

I have a simple react movies app, search bar component for searching a specific movie and main content component that shows popular movies.我有一个简单的反应电影应用程序,用于搜索特定电影的搜索栏组件和显示热门电影的主要内容组件。

when a user search for a specific movie the movie is displayed under the search bar component and I want that the movie will be displayed instead of the main content component, I try to do it with useState but got nothing当用户搜索特定电影时,该电影显示在搜索栏组件下,并且我希望显示该电影而不是主要内容组件,我尝试使用 useState 执行此操作,但一无所获

here is my code:这是我的代码:

import React from 'react'
import MainContent from '../../component/MainContent/MainContent'
import SearchBar from '../../component/SearchBar/SearchBar'

export default function HomePage() {
    return (
        <div>
            <SearchBar />
            <MainContent />
        </div>
    )
}
import React, { useState, useEffect } from 'react';
import Slider from "react-slick";
import Loading from '../Loading';
import './mainContent.css';
import MovieCard from '../MovieCard/MovieCard';

export default function MainContent() {

    const [allMovies, setAllMovies] = useState([]);
    const [isLoading, setIsLoading] = useState(false);

    const moviesDisplay = async () => {
        try {
            setIsLoading(true);
            const api_url = 'http://localhost:4000/movies';
            await fetch(api_url)
                .then(res => res.json())
                .then(results => {
                    // console.log(results.results)
                    setAllMovies(results.results)
                })
        } catch (err) {
            console.error('failed to fetch');
        } finally {
            setIsLoading(false);
        }
    }
    useEffect(() => {
        moviesDisplay();
    }, []);

    const settings = {
        infinite: true,
        slidesToShow: 5,
        slidesToScroll: 2,
        arrows: true,
        autoplay: true,
        autoplaySpeed: 3000,
        pauseOnHover: true,
        responsive: [
            {
                breakpoint: 1024,
                settings: {
                    slidesToShow: 4,
                    slidesToScroll: 4,
                    infinite: true,
                }
            }, {
                breakpoint: 800,
                settings: {
                    slidesToShow: 3,
                    slidesToScroll: 3,
                    initialSlide: 1
                }
            },
            {
                breakpoint: 600,
                settings: {
                    slidesToShow: 2,
                    slidesToScroll: 2,
                    initialSlide: 2
                }
            },
            {
                breakpoint: 480,
                settings: {
                    slidesToShow: 1,
                    slidesToScroll: 1
                }
            }
        ]
    };

    return (

        <div className='moviesContainer'>
            <div className='moviesCarousel'>
                {isLoading && <Loading />}
                <Slider {...settings}>
                    {allMovies && allMovies.filter(movie => movie.poster_path).map((movie) =>
                        <div className="movieCard" key={movie.id}>
                            <MovieCard poster_path={'https://image.tmdb.org/t/p/w300' + movie.poster_path} title={movie.title}
                                release_date={movie.release_date} vote_average={movie.vote_average} overview={movie.overview} />
                        </div>
                    )}
                </Slider>
            </div>
        </div>
    )
}
import React, { useEffect, useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Loading from '../Loading';
import MovieCard from '../MovieCard/MovieCard';

import './searchBar.css';

export default function SearchBar(props) {

    const [movies, setMovies] = useState([]);
    const [query, setQuery] = useState('');
    const [isLoading, setIsLoading] = useState(false)

    const movieSearch = async (API) => {
        setIsLoading(true);
        await fetch(API)
            .then((res) => res.json())
            .then((data) => {
                setMovies(data.results[0])
                setIsLoading(false)
            });
    }

    const handleSubmit = (e) => {
        console.log(query)
        if (query !== '') {
            movieSearch(
                `http://localhost:4000/movie/${query}`
            )
            setQuery('')
        }
        e.preventDefault()
    }

    const handleChange = (e) => {
        setQuery(e.target.value)
    }

    return (
        <>
            <div className='searchMovieInput'>
                <form onSubmit={handleSubmit}>
                    <input type="text" placeholder="Search.." value={query} onChange={handleChange} />
                    <button type="submit"><FontAwesomeIcon icon='search' size='lg' color='chocolate' /></button>
                </form>

                {isLoading && <Loading />}
                <div className="movie-card">
                    <MovieCard poster_path={movies.poster_path} {...movies} key={movies.id} />
                </div>
            </div>
        </>
    )
}

You need share state between components SearchBar and MainContent.您需要在组件 SearchBar 和 MainContent 之间共享 state。 I know how to do this with Context or State management like redux, Mobx我知道如何使用 Context 或 State 管理来做到这一点,例如 redux、Mobx

import React from "react";

const Context = React.createContext({
    visibleMainContent: true,
    setVisibleMainContent: () => {},
});

const SearchBar = (props) => {
    const {visibleMainContent, setVisibleMainContent} = React.useContext(Context)
    return <div>
        <button onClick={()=> setVisibleMainContent(!visibleMainContent)}>{visibleMainContent ? "Hide" : "Show"}</button>
    </div>;
};

const MainContent = (props) => {
    const {visibleMainContent} = React.useContext(Context)
    return <div style={{display: visibleMainContent ? "block" : "none"}}>Main Content</div>;
};

export default function App () {
    const [visibleMainContent, setVisibleMainContent] = React.useState("en");
    const visibleMC = { visibleMainContent, setVisibleMainContent };
    return (
        <Context.Provider value={visibleMC} >
            <div>
                <SearchBar />
                <MainContent />
            </div>
        </Context.Provider>
    );
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从同一页面的不同部分单击基于按钮的同一页面中的动态组件? - How to render dynamic component in the same page based button click from different section of same page? 如何使用不同的道具渲染相同的组件 - How to render the same component with different props 如何在同一组件上呈现不同样式的 css? - How to render different style css on same component? React:如何使用相同的onClick和不同的drop渲染相同的组件 - React: How to render same component with same onClick and different drops 如何为具有不同价值道具的不同路线呈现相同的反应成分? - How to render same react component for different routes with different value props? 如何渲染在APP不同地方定义的同一个React组件实例? - How to render the same instance of a React component that are defined in different places of the APP? 如何渲染同一组件的不同布局? - How can I render different layouts of same component? 如何根据用户当前所在的页面呈现相同的组件? - How do I render same component depending on the page the user is currently on? 使用不同的参数重新渲染相同的组件 - Re-render the same component with different parameter 如何用不同的数据渲染相同的 Angular 组件? 我有一个基于 url 部分呈现的 Angular 组件 - How to render a same Angular component with different data? I have an Angular component which renders based on the part of the url
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM