【问题标题】:What is the best way to render a search bar component that takes in a props in another component using react v6使用 react v6 呈现在另一个组件中接收道具的搜索栏组件的最佳方法是什么
【发布时间】:2022-11-21 12:22:29
【问题描述】:

我有我的搜索组件,它应该传递到标头组件,但我使用的教程是旧的,并且使用的是旧版本的 React。

这是我的 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

每当我运行代码时,它都会告诉我需要将它包装在 &lt;Routes&gt;

我是这样做的

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

但是当我像这样包装它时它不会给出任何错误但是搜索栏根本不会显示在我的浏览器标题中

请问渲染这个的正确方法是什么?

我还读到我的 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 组件中正确渲染它

【问题讨论】:

  • 您需要将路径设置为&lt;Route path="/some-path" /&gt;。路由器不知道要渲染它。您也不需要使用渲染道具将历史记录传递给&lt;Search /&gt;。只需使用 useHistory 钩子。

标签: javascript html reactjs search react-router


【解决方案1】:

据我所知,您正在使用 react-router-dom v6,因此您使用 useNavigate 挂钩的 Search 组件的最后一个 sn-p 是正确的。

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 功能属性消失了。路由属性也不见了,即historylocationmatch,这就是为什么你需要useNavigate钩子来获取Search中的navigate函数。

据我所知,Search 在旧教程中仅由 Route 渲染,只是为了将 history 对象作为道具传入。我看不出有任何理由让它由 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 挂钩将起作用。

【讨论】:

  • 谢谢它终于显示在我的标题中。我的 App.js 使用 BrowserRouter。我按照你说的做了,我的搜索组件中的 console.log 显示了我在搜索栏中键入的任何关键字,但是当我单击搜索时,它会按原样转到 /search/$keyword 但没有返回数据,当我在邮递员中测试它可以工作的路线,但在浏览器中它没有。为什么不请?
  • @JoeySmith 当您导航到`/search/${keyword}` 时,您希望返回什么数据,您希望它返回什么地方/什么地方?组件是否开启路线路径应该获取一些数据?对于您在此处发布的问题,这似乎是课外活动。
  • 在您的帮助下,我的搜索栏真正起作用了。但是我的后端有一个问题,我没有早点意识到。我刚刚修复了我的 productController 以获得所有产品及其正常工作。问我它在哪里获取数据让我一行一行地检查我的后端。再次,谢谢你
  • @JoeySmith 太棒了!很高兴听到听起来您解决了那个挥之不去的问题。干杯。
【解决方案2】:

我在这里遇到同样的问题。你是如何修复后端产品控制器的?

【讨论】:

  • xxhush,请不要添加我也是作为答案。它实际上并没有提供问题的答案。如果您有不同但相关的问题,请ask它(如果它有助于提供上下文,请参考此问题)。如果你对这个具体问题感兴趣,你可以upvote它,留下comment,或者一旦你有足够的reputation就开始bounty
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-29
  • 2019-01-25
  • 2018-12-29
  • 2018-12-01
  • 2019-11-25
  • 2020-06-03
相关资源
最近更新 更多