簡體   English   中英

使用 react v6 呈現在另一個組件中接收道具的搜索欄組件的最佳方法是什么

[英]What is the best way to render a search bar component that takes in a props in another component using react v6

我有我的搜索組件,它應該傳遞到 header 組件,但我使用的教程是舊的,並且使用的是舊版本的反應。

這是我的 Search.js 組件。

import React, { useState } from 'react'
import { useParams, useNavigate } from 'react-router-dom'

const Search = ({ history }) => {

    const [keyword, setKeyword] = useState('');

    const searchHandler = (e) => {
        e.preventDefault()

        if (keyword.trim()) {
            history.push(`/search/${keyword}`)
        } else {
            history.push('/')
        }
    }

    console.log('my keyword', keyword);

    return (
            <form onSubmit={searchHandler}>
                 <div className="input-group">
                    <input
                        type="text"
                        id="search_field"
                        className="form-control"
                        placeholder="Enter Product Name ..."
                        onChange={(e) => setKeyword(e.target.value)}
                    />
                    <div className="input-group-append">
                        <button id="search_btn" className="btn">
                        <i className="fa fa-search" aria-hidden="true"></i>
                        </button>
                    </div>
        </div>
            </form>       
    )
}

export default Search

這就是我將它傳遞到我的 Header.js 組件的方式

import React, { Fragment } from 'react'
import { Route, Link } from 'react-router-dom'

import { useDispatch, useSelector } from 'react-redux'
import { useAlert } from 'react-alert'
import { logout } from '../../actions/userActions'

import Search from './Search'

import '../../App.css'

const Header = () => {
    
    
    return (
        <Fragment>
            <nav className="navbar row">
                <div className="col-12 col-md-6 mt-2 mt-md-0">
                
                    <Route render={({ history }) => <Search history={history} />} />
                    
                </div>
             </nav>
        </Fragment>
    )
}

export default Header

每當我運行代碼時,它都會告訴我需要將它包裝在<Routes>

我是這樣做的

<Routes> 
  <Route render={({ history }) => <Search history={history} />} />
</Routes>

但是當我像這樣包裝它時它不會給出任何錯誤但搜索欄根本不會在我的瀏覽器中顯示 header

請問渲染這個的正確方法是什么?

我還讀到我的 search.js 中的history.push已被useNavigate取代,所以我嘗試更改它以使我的 Search.js 看起來像這樣

import React, { useState } from 'react'
import { useParams, useNavigate } from 'react-router-dom'

const Search = ({  }) => {
   
    const [keyword, setKeyword] = useState('');
    const navigate = useNavigate();

    const searchHandler = (e) => {
        e.preventDefault()

        if (keyword.trim()) {
            navigate(`/search/${keyword}`)
        } else {
            navigate('/search')
        }
    }

    console.log('my keyword', keyword);

    return (
            <form onSubmit={searchHandler}>
                 <div className="input-group">
                    <input
                        type="text"
                        id="search_field"
                        className="form-control"
                        placeholder="Enter Product Name ..."
                        onChange={(e) => setKeyword(e.target.value)}
                    />
                    <div className="input-group-append">
                        <button id="search_btn" className="btn">
                        <i className="fa fa-search" aria-hidden="true"></i>
                        </button>
                    </div>
        </div>
            </form>       
    )
}

export default Search

但我不知道如何在我的Header組件中正確渲染它

據我所知,您正在使用react-router-dom v6,因此您使用useNavigate掛鈎的Search組件的最后一個片段是正確的。

const Search = () => {
  const [keyword, setKeyword] = useState("");
  const navigate = useNavigate();

  const searchHandler = (e) => {
    e.preventDefault();

    if (keyword.trim()) {
      navigate(`/search/${keyword}`);
    } else {
      navigate("/search");
    }
  };

  console.log("my keyword", keyword);

  return (
    <form onSubmit={searchHandler}>
      <div className="input-group">
        <input
          type="text"
          id="search_field"
          className="form-control"
          placeholder="Enter Product Name ..."
          onChange={(e) => setKeyword(e.target.value)}
        />
        <div className="input-group-append">
          <button id="search_btn" className="btn">
            <i className="fa fa-search" aria-hidden="true"></i>
          </button>
        </div>
      </div>
    </form>
  );
};

但問題是您正在嘗試使用較舊的 RRDv5 Route API 在Route上呈現它。

<Route render={({ history }) => <Search history={history} />} />

在 v6 中, componentrenderchildren function 道具消失了。 路由道具也不見了,即historylocationmatch ,這就是為什么你需要useNavigate鈎子來在Search中獲取navigate function 。

據我所知, Search僅由舊教程中的Route呈現,只是為了將history object 作為 prop 傳入。 我看不出有任何理由讓它由Route呈現。 直接在Header中渲染Search

const Header = () => {
  return (
    <nav className="navbar row">
      <div className="col-12 col-md-6 mt-2 mt-md-0">
        <Search />
      </div>
    </nav>
  );
};

假設Header組件在路由器( BrowserRouterHashRouterMemoryRouter)提供的路由上下文中呈現, useNavigate鈎子將起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM