我正在切换到使用 Hooks 构建组件,并且我正在努力使用useRef()
设置 refs
父级(ref 目前仅添加到一个组件中,因为我想在将功能扩展到其他组件之前确保它有效):
export default function UserPanels({ selected_client } ) {
const classes = useStyles();
const [value, setValue] = useState(0);
const container = useRef( null );
function handleChange(event, newValue) {
setValue(newValue);
container.current.displayData();
}
return (
<div className={classes.root}>
<UserTabs
value={value}
onChange={handleChange}
indicatorColor="primary"
textColor="primary"
variant="fullWidth"
aria-label="full width tabs example"
>
<Tab label='Service User' {...a11yProps(0)} />
<Tab label='Care Plan' {...a11yProps(1)} />
<Tab label='Contacts' {...a11yProps(2)} />
<Tab label='Property' {...a11yProps(3)} />
<Tab label='Schedule' {...a11yProps(4)} />
<Tab label='Account' {...a11yProps(5)} />
<Tab label='Invoices' {...a11yProps(6)} />
<Tab label='Notes' {...a11yProps(7)} />
<Tab label='eMAR' {...a11yProps(8)} />
</UserTabs>
<TabPanel value={value} index={0}>
<UserDetailsContainer
selected_client={ selected_client }
/>
</TabPanel>
<TabPanel value={value} index={1}>
Care Plan
</TabPanel>
<TabPanel value={value} index={2}>
<ContactsContainer
ref={ container }
selected_client={ selected_client }
/>
</TabPanel>
<TabPanel value={value} index={3}>
Property
</TabPanel>
<TabPanel value={value} index={4}>
Schedule
</TabPanel>
<TabPanel value={value} index={5}>
Account
</TabPanel>
<TabPanel value={value} index={6}>
Invoices
</TabPanel>
<TabPanel value={value} index={7}>
Notes
</TabPanel>
<TabPanel value={value} index={8}>
eMAR
</TabPanel>
</div>
);
}
孩子:
export default function ContactsContainer( props ) {
const [ state, setState ] = useState({
contact_records: contacts,
data_ready: true
});
function displayData() {
console.log( 'display time' );
}
if ( !state.data_ready ) return null
return (
<>
{
state.contact_records.map( ( contact ) => {
return <ContactRecord contact={ contact } />
} )
}
</>
)
}
本质上,我正在尝试从父函数调用子函数,但ref.current
计算结果为null
,当调用handleChange()
时,我收到错误container.current is null
,并且我经常看到错误Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
请注意,我已经测试了forwardRef
:
<ContactsContainer
ref={ container }
selected_client={ selected_client }
/>
而且,虽然这消除了错误,但它并不能解决问题。我从来没有遇到过使用带有类组件的 refs 的问题,但我似乎在这里缺少一些东西。
首先,不要过度使用refs
(反应文档)。您不能通过直接调用其函数来控制子组件(老实说,您无法使用函数组件执行此操作)。
如果您需要在子组件中显示某些内容,则必须在父组件中准备数据并通过 props 传递该数据。孩子应该尽可能简单。他们应该得到道具并显示一些数据。
在父级中:
const [value, setValue] = useState(0);
const [time, setTime] = useState(null);
function handleChange(event, newValue) {
setValue(newValue);
setTime('display time');
}
return (
....
<ContactsContainer
time={time}
selected_client={ selected_client }
/>
....
)
如果你需要在 props 更改时在孩子身上产生一些副作用(例如进行 HTTP 调用、调度 Redux 操作),你必须使用useEffect
钩子。
在父级中:
<ContactsContainer
value={value}
selected_client={ selected_client }
/>
在儿童中:
useEffect(() => {
console.log('display time action');
}, [props.value]);
你可以将 ref 作为道具传递:
// ...
const infoRef=useRef(null)
useEffect(()=>{
if(infoRef.current) infoRef.current()
},[])
return <ChildComponent infoRef={infoRef} />
然后在孩子身上:
useEffect(()=>{
infoRef.current=childFunctionToExecuteInParent
},[])