我要改用Hooks构建组件,而我正努力用useRef()
设置引用
父项(当前仅将引用添加到一个组件,因为我想确保在将功能扩展到其他组件之前可以正常工作):
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 }
/>
并且,尽管这消除了错误,但不能解决问题。我从来没有在类组件上使用ref的问题,但这里似乎缺少了一些东西。
答案 0 :(得分:2)
首先,请不要过度使用refs
(react doc)。您不能直接调用子组件的功能来控制子组件(老实说,您不能使用功能组件来做到这一点)。
如果需要在子级中显示某些内容,则必须在父级组件中准备数据并通过道具传递该数据。儿童应尽可能简单。他们应该得到道具并显示一些数据。
在父母中:
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 }
/>
....
)
如果在道具更改时需要在孩子中产生一些副作用(例如,进行HTTP调用,调度Redux操作),则必须使用useEffect
钩子。
在父母中:
<ContactsContainer
value={value}
selected_client={ selected_client }
/>
在儿童中:
useEffect(() => {
console.log('display time action');
}, [props.value]);
答案 1 :(得分:0)
您可以将 ref 作为道具传递:
// ...
const infoRef=useRef(null)
useEffect(()=>{
if(infoRef.current) infoRef.current()
},[])
return <ChildComponent infoRef={infoRef} />
然后在孩子:
useEffect(()=>{
infoRef.current=childFunctionToExecuteInParent
},[])