Reactjs 如何将ref传递给相邻组件
我试图在我的标题组件中的搜索输入上使用ref,它不是我的ResultsList组件的高阶组件。我想从ResultsList组件将焦点设置在标题的搜索输入上。这是直观的从标题,因为我所要做的是下面。如果我想在ResultsList中创建一个按钮,该按钮将集中在标题中的输入元素上,该怎么办?我怎么通过这个裁判?我已经阅读了forwardRef,但我不会将我的ref转发。ResultsList不是标头的子级Reactjs 如何将ref传递给相邻组件,reactjs,use-ref,Reactjs,Use Ref,我试图在我的标题组件中的搜索输入上使用ref,它不是我的ResultsList组件的高阶组件。我想从ResultsList组件将焦点设置在标题的搜索输入上。这是直观的从标题,因为我所要做的是下面。如果我想在ResultsList中创建一个按钮,该按钮将集中在标题中的输入元素上,该怎么办?我怎么通过这个裁判?我已经阅读了forwardRef,但我不会将我的ref转发。ResultsList不是标头的子级 import React,{useState,useRef}来自“React”; 从'rea
import React,{useState,useRef}来自“React”;
从'react router dom'导入{useHistory};
常量头=()=>{
const searchInput=useRef(null);
const history=useHistory();
const[searchValue,setSearchValue]=useState(关键字);
函数句柄更改(事件){
setSearchValue(事件目标值);
}
函数handleSearch(事件){
event.preventDefault();
如果(搜索值){
history.push(`/search/${searchValue}`);
}否则{
searchInput.current.focus();
}
}
返回(
);
}
导出默认标题代码>您需要使用“提升状态提升”模式。在App
中声明react ref,并将其传递给两个组件,传递到标题
将ref附加到节点,传递到结果列表
访问ref并设置“焦点”
同样,您也可以访问ResultsList
组件中的searchInputRef
function ResultsList({ searchInputRef }) {
...
<button
type="button"
onClick={() => searchInputRef.current?.focus()}
>
Set Search Focus
</button>
}
为应用程序中的儿童提供上下文
import SearchInputRefContext from '.....';
function App() {
const searchInputRef = useRef(null);
return (
<SearchInputRefContext.Provider value={searchInputRef}>
<Header />
<ResultsList />
</SearchInputRefContext.Provider>
);
}
从“…”导入SearchInputRefContext;
函数App(){
const searchInputRef=useRef(null);
返回(
);
}
访问任何子组件中的上下文
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>
);
}
const头=()=>{
const history=useHistory();
const searchInputRef=useContext(SearchInputRefContext);
const[searchValue,setSearchValue]=useState(关键字);
函数句柄更改(事件){
setSearchValue(事件目标值);
}
函数handleSearch(事件){
event.preventDefault();
如果(搜索值){
history.push(`/search/${searchValue}`);
}否则{
searchInputRef.current.focus();
}
}
返回(
);
}
不管嵌套有多深
function ReallyDeepComponent() {
const searchInputRef = useContext(SearchInputRefContext);
...
<button
type="button"
onClick={() => searchInputRef.current?.focus()}
>
Set Search Focus
</button>
}
函数reallydepcomponent(){
const searchInputRef=useContext(SearchInputRefContext);
...
searchInputRef.current?.focus()}
>
设置搜索焦点
}
如果您仍在使用基于类的组件,请查看此信息。查看forwardRef
:@SakoBu我在说明中提到过,但我添加按钮的结果列表不是标题的子项。如果我没有弄错,您可以使用React上下文进行操作。请看以下内容ForwardRef
也可以工作,但您需要将其传递给这两个组件-请参阅演示。我更喜欢使用上下文,但两者都可以。是的,我想到了,但是如果我的ResultsList在层次结构中嵌入得更深,比如ResultsPage>ResultsList呢?我要把它传给道具两次吗?这是一种常见的做法吗?@laziotibjczyk将道具向下传递一级是很常见的,下一级或更高的道具可能不太常见。这种模式被称为“道具钻孔”,在这里你可以将道具穿过许多层。react提供的解决方案是“提供了一种通过组件树传递数据的方法,而无需在每个级别手动传递道具。”您可以创建一个上下文,提供共享引用和组件,只要它们位于提供程序的子树中,可以访问上下文值。@laziotibjczyk如果有兴趣,我可以更新我的答案,并尝试提供更多详细信息。@laziotibjczyk当然可以。我不觉得这不合理,因为它解决了“支柱钻井”的问题。我想您会发现代码非常简洁明了。@laziotibjczyk。它基本上是一个空检查,因此searchInputRef.current?.focus()
相当于searchInputRef.current&&searchInputRef.current.focus()
。
import SearchInputRefContext from '.....';
function App() {
const searchInputRef = useRef(null);
return (
<SearchInputRefContext.Provider value={searchInputRef}>
<Header />
<ResultsList />
</SearchInputRefContext.Provider>
);
}
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>
);
}
function ReallyDeepComponent() {
const searchInputRef = useContext(SearchInputRefContext);
...
<button
type="button"
onClick={() => searchInputRef.current?.focus()}
>
Set Search Focus
</button>
}