javascript - 将多个 refs 传递给子组件
问题描述
在深入探讨主要问题之前,我的用例是我试图将滚动处理到所需的部分。我将在左侧有导航,并在右侧有相对于这些导航的表单部分列表。和是子组件Navigation
。Form Section
这是我构建代码的方式
Parent.js
const scrollToRef = ref => window.scrollTo(0, ref.current.offsetTop);
const Profile = () => {
const socialRef = React.useRef(null);
const smsRef = React.useRef(null);
const handleScroll = ref => {
console.log("scrollRef", ref);
scrollToRef(ref);
};
return (
<>
<Wrapper>
<Grid>
<Row>
<Col xs={12} md={3} sm={12}>
<Navigation
socialRef={socialRef}
smsRef={smsRef}
handleScroll={handleScroll}
/>
</Col>
<Col xs={12} md={9} sm={12}>
<Form
socialRef={socialRef}
smsRef={smsRef}
/>
</Col>
</Row>
</Grid>
</Wrapper>
</>
);
};
Navigation.js(child component)
我尝试使用 forwardRef 但似乎它只接受一个参数作为 ref 虽然我有多个 refs。
const Navigation = React.forwardRef(({ handleScroll }, ref) => {
// it only accepts on ref argument
const items = [
{ id: 1, name: "Social connections", pointer: "social-connections", to: ref }, // socialRef
{ id: 2, name: "SMS preference", pointer: "sms", to: ref }, // smsRef
];
return (
<>
<Box>
<UL>
{items.map(item => {
return (
<LI
key={item.id}
active={item.active}
onClick={() => handleScroll(item.to)}
>
{item.name}
</LI>
);
})}
</UL>
</Box>
</>
);
});
export default Navigation;
Form.js
我不知道在使用 forwardRef 时传递多个引用,因此对于表单部分,我已将引用作为简单的道具传递。
const Form = ({ socialRef, smsRef }) => {
return (
<>
<Formik initialValues={initialValues()}>
{({ handleSubmit }) => {
return (
<form onSubmit={handleSubmit}>
<Social socialRef={socialRef} />
<SMS smsRef={smsRef} />
</form>
);
}}
</Formik>
</>
);
};
社交.js
const Social = ({ socialRef }) => {
return (
<>
<Row ref={socialRef}>
<Col xs={12} md={3}>
<Label>Social connections</Label>
</Col>
<Col xs={12} md={6}></Col>
</Row>
</>
);
};
任何人都可以帮助我传递多个引用,因此当单击特定导航项时,它应该将我滚动到其各自的组件(部分)。
解决方案
我在下面添加了一个示例。我没有测试过这个。这只是想法。
import React, { createContext, useState, useContext, useRef, useEffect } from 'react'
export const RefContext = createContext({});
export const RefContextProvider = ({ children }) => {
const [refs, setRefs] = useState({});
return <RefContext.Provider value={{ refs, setRefs }}>
{children}
</RefContext.Provider>;
};
const Profile = ({ children }) => {
// ---------------- Here you can access refs set in the Navigation
const { refs } = useContext(RefContext);
console.log(refs.socialRef, refs.smsRef);
return <>
{children}
</>;
};
const Navigation = () => {
const socialRef = useRef(null);
const smsRef = useRef(null);
const { setRefs } = useContext(RefContext);
// --------------- Here you add the refs to context
useEffect(() => {
if (socialRef && smsRef) {
setRefs({ socialRef, smsRef });
}
}, [socialRef, smsRef, setRefs]);
return <>
<div ref={socialRef}></div>
<div ref={smsRef}></div>
</>
};
export const Example = () => {
return (
<RefContextProvider>
<Profile>
<Navigation />
</Profile>
</RefContextProvider>
);
};
推荐阅读
- javascript - 使用 Object Javascript 在 foreach 循环中的最后一次迭代
- postman - 邮递员在收集开始时定义变量列表一次
- javascript - 如何从“日期范围选择器”禁用每天的“点击”事件?
- embedded - 使用 srec_cat 加入三个二进制文件并填充漏洞
- ember.js - Ember-cli-build,排除组件 ember 插件
- python - 如何从 Process- 或 Thread 实例返回值?
- javascript - Axios 在控制台上打印值但返回未定义
- linux - 在 @INC 中找不到 Parallel/ForkManager.pm
- c++ - C和C++中前缀自增运算符的区别
- php - Laravel Mail 未将变量传递给刀片模板