Laz*_*zyk 7 reactjs react-hooks use-ref
我试图在我的 Header 组件中的搜索输入上使用 ref ,它不是我的 ResultsList 组件的高阶组件。我想将焦点集中在 ResultsList 组件的标题搜索输入上。从标题来看它很直观,因为我所要做的就是下面的内容。如果我想在 ResultsList 中创建一个专注于 Header 中的输入元素的按钮该怎么办?我如何通过这个参考?我已经阅读过有关forwardRef的内容,但我没有将我的参考转发。ResultsList 不是 Header 的子项。
import React, { useState, useRef } from 'react';
import { useHistory } from 'react-router-dom';
const Header = () => {
const searchInput = useRef(null);
const history = useHistory();
const [searchValue, setSearchValue] = useState(keyword);
function handleChange(event) {
setSearchValue(event.target.value);
}
function handleSearch(event) {
event.preventDefault();
if(searchValue) {
history.push(`/search/${searchValue}`);
} else {
searchInput.current.focus();
}
}
return (
<form onSubmit={handleSearch} role="search">
<input
value={searchValue}
onChange={handleChange}
className="HeaderSearch__input"
id="header-search-input"
placeholder="Search a repository"
ref={searchInput}>
</input>
</form>
);
}
export default Header;
Run Code Online (Sandbox Code Playgroud)
我的应用程序组件看起来像这样
import React from 'react';
import Header from './Header';
import ResultsList from './ResultsList';
function App() {
return (
<>
<Header />
<ResultsList />
</>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)
您将需要利用“提升状态”模式。声明react ref并将App其传递给两个组件,toHeader将ref附加到节点,toResultsList访问ref并设置“焦点”。
function App() {
const searchInputRef = useRef(null);
return (
<>
<Header searchInputRef={searchInputRef} />
<ResultsList searchInputRef={searchInputRef} />
</>
);
}
Run Code Online (Sandbox Code Playgroud)
附加并使用您已经在的引用Header
const Header = ({ searchInputRef }) => {
const history = useHistory();
const [searchValue, setSearchValue] = useState(keyword);
function handleChange(event) {
setSearchValue(event.target.value);
}
function handleSearch(event) {
event.preventDefault();
if(searchValue) {
history.push(`/search/${searchValue}`);
} else {
searchInputRef.current.focus();
}
}
return (
<form onSubmit={handleSearch} role="search">
<input
value={searchValue}
onChange={handleChange}
className="HeaderSearch__input"
id="header-search-input"
placeholder="Search a repository"
ref={searchInputRef}>
</input>
</form>
);
}
Run Code Online (Sandbox Code Playgroud)
同样,您也可以在组件searchInputRef中访问。ResultsList
function ResultsList({ searchInputRef }) {
...
<button
type="button"
onClick={() => searchInputRef.current?.focus()}
>
Set Search Focus
</button>
}
Run Code Online (Sandbox Code Playgroud)
如果嵌套更深的组件需要引用怎么办?
如果子组件不是直接后代,那么您可以利用 React 上下文来允许子组件访问 ref,而无需将其作为 prop 通过 React 树传递。
创建并导出上下文。
const SearchInputRefContext = React.createContext(null);
Run Code Online (Sandbox Code Playgroud)
为儿童提供背景App
import SearchInputRefContext from '.....';
function App() {
const searchInputRef = useRef(null);
return (
<SearchInputRefContext.Provider value={searchInputRef}>
<Header />
<ResultsList />
</SearchInputRefContext.Provider>
);
}
Run Code Online (Sandbox Code Playgroud)
访问任何子子组件中的上下文
const Header = () => {
const history = useHistory();
const searchInputRef = useContext(SearchInputRefContext);
const [searchValue, setSearchValue] = useState(keyword);
function handleChange(event) {
setSearchValue(event.target.value);
}
function handleSearch(event) {
event.preventDefault();
if(searchValue) {
history.push(`/search/${searchValue}`);
} else {
searchInputRef.current.focus();
}
}
return (
<form onSubmit={handleSearch} role="search">
<input
value={searchValue}
onChange={handleChange}
className="HeaderSearch__input"
id="header-search-input"
placeholder="Search a repository"
ref={searchInputRef}>
</input>
</form>
);
}
Run Code Online (Sandbox Code Playgroud)
无论嵌套多深
function ReallyDeepComponent() {
const searchInputRef = useContext(SearchInputRefContext);
...
<button
type="button"
onClick={() => searchInputRef.current?.focus()}
>
Set Search Focus
</button>
}
Run Code Online (Sandbox Code Playgroud)
如果您碰巧仍在使用基于类的组件,请参阅本节。
| 归档时间: |
|
| 查看次数: |
5324 次 |
| 最近记录: |