繁体   English   中英

State 不在不同的组件中更新

[英]State not updating in different component

我有一个搜索栏组件,我使用上下文导入另一个组件。 搜索栏的 state 在其自己的组件中有效,但是当我使用上下文将其导入另一个组件时,它不起作用。 我在我的项目中使用了其他上下文并且它们有效,但搜索栏 state 没有。 我不知道从哪里开始,或者如何修复它。 有人可以指出我正确的方向吗?

export const SearchInput = () => {
const [searchInput, setSearchInput] = useState('');

    const handleSubmit = (e) => {
        e.preventDefault()
    }

    return (
        <div>
            <form onSubmit={handleSubmit}>
                <input type='text'
                    className='search-input'
                    name='search-movies'
                    value={searchInput}
                    onChange={(e) => setSearchInput(e.target.value)} />
            </form>
        </div>
    )
}

//Use Context Component

export const SearchContext = React.createContext()

export function SearchProvider({ children }) {
    const [searchInput, setSearchInput] = useState('');
    

    const value = {
        searchInput
    }

    return (
        <div>
            <SearchContext.Provider value={value}>
                {children}
            </SearchContext.Provider>
        </div>
    )
}

const Movies = () => {

    const { data, loading, isErr } = useFetch([
        `https://api.themoviedb.org/3/list/7077601?api_key=${process.env.REACT_APP_API_KEY}&language=en-US`,
        `https://api.themoviedb.org/3/list/7078334?api_key=${process.env.REACT_APP_API_KEY}&language=en-US`,
        `https://api.themoviedb.org/3/list/7078244?api_key=${process.env.REACT_APP_API_KEY}&language=en-US`
    ]);

    const { watchList, handleClick } = useContext(WatchListContext);
    const { searchInput } = useContext(SearchContext)

    const [moviePoster, setmoviePoster] = useState(`giphy (1).gif`);
    const [movieTitle, setmovieTitle] = useState('');
    const [movieDescription, setmovieDescription] = useState('')

    const styles = {
        backgroundImage: `url(${moviePoster})`
    };


    SwiperCore.use([Navigation, Pagination, Scrollbar, A11y]);

    return (

        <div className='movie-container'>
            {isErr && <div className="error">{isErr}</div>}
            {loading && <Spinner animation="border" variant="secondary" className="spinner" >
                <span>Loading...</span>
            </Spinner>}
            <div className='movie-hero' style={styles}></div>
            <div className="contains-descriptions">
                <h2 className="hero-movie-title show-movie">{movieTitle}</h2>
                <p className="hero-movie-description show-movie">{movieDescription}</p>
            </div>

            <section className="movies">
                <h2 style={{ color: 'white', marginLeft: '20px' }}>Action </h2>
                {data && <Swiper
                    spaceBetween={10}
                    slidesPerView={6}
                    pagination={{ clickable: true }}
                    scrollbar={{ draggable: true }}
                    onSlideChange={() => console.log('slide change')}
                    onSwiper={(swiper) => console.log(swiper)}
                >
                    {data && data[0].items.map(movie =>
                        <SwiperSlide key={movie.id}>
                            <div className='movie' >
                                <img onMouseOver={() => {
                                    setmoviePoster(`${"https://image.tmdb.org/t/p/original" + movie.poster_path}`);
                                    setmovieTitle(movie.original_title);
                                    setmovieDescription(movie.overview);
                                }}
                                    src={'https://image.tmdb.org/t/p/original' + movie.poster_path} width='250' height='300'
                                    alt='Promotional Poster For Movie'
                                />
                                <button className="watchlist-btn"
                                    onClick={() => handleClick(movie.original_title)}>
                                    {watchList.includes(movie.original_title) ?
                                        <i className="fas fa-minus-circle"></i> :
                                        <i className="fas fa-plus-circle"></i>}
                                </button>
                            </div>
                        </SwiperSlide>
                    )
                    }
                </Swiper>}
            </section>

我假设一个组件树看起来像这样:

+-- SearchProvider
|   +-- SearchInput
|   +-- Movies

您的SearchProvider应该同时提供 state 和 state 设置器作为其值:

export const SearchContext = React.createContext()

export function SearchProvider({ children }) {
    const [searchInput, setSearchInput] = useState('');
    
    const value = {
        searchInput,
        setSearchInput
    };

    return ...
}

您的SearchInput不应再控制其自己的本地 state。 state 现在必须与树的 rest 共享。 相反,它订阅上下文并直接更新它:

export const SearchInput = () => {
    const { searchInput, setSearchInput } = React.useContext(SearchContext);

    const handleSubmit = (e) => {
        e.preventDefault()
    };

    return ...
}

为什么你使用上下文而不只是 useState 和 props?

我认为它适用于以下内容:

export const SearchInput = (props) => {

    const handleSubmit = (e) => {
        e.preventDefault()
    }

    return (
        <div>
            <form onSubmit={handleSubmit}>
                <input type='text'
                    className='search-input'
                    name='search-movies'
                    value={props.value}
                    onChange={(e) => props.onChange(e.target.value)} />
            </form>
            {props.children}
        </div>
    )
}


export function SearchCompoent({ children }) {
    const [searchInputValue, setSearchInputValue] = useState('');
    return (
        <SearchInput value={searchInputValue}>
            {children}
        </SearchInput>
    )
}

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM