如何使用react-router-dom的转发参考



我已经理解转发Refs和react-router-dom的概念。但在这个实现中,我不确定如何正确使用它。我有一个子组件,其中有一个在useState中设置null的函数。我希望每次单击呈现此子组件的菜单项时都执行此函数。这个菜单被挂载在应用中的com列表和Router中,如下面的3个文件所示。确切地说,我不知道在哪里把useRef执行子函数resetMyState,如果它在App.js或appbaranddraw .js以及如何做到这一点。

childComponent.js

...
const MeusAnuncios = forwardRef((props, ref) => {
const [myState, setMyState] = useState(null);

function resetMyState(){
setMyState(null)
}
async function chargeMyState() {
await
...
setMyState(values)
...
}
...

AppBarAndDrawer.js

...
const drawer = (
<div>
<div className={classes.toolbar} />
<Divider />
<List>
{[
{ label: "Minha Conta", text: "minhaConta", icon: "person" },
{ label: "Novo Anúncio", text: "novoAnuncio", icon: "queue_play_next" },
{ label: "Meus Anúncios", text: "meusAnuncios", icon: "dvr" },
{ label: "Estatísticas", text: "estatisticas", icon: "line_style" },
{ label: "Faturamento", text: "faturamento", icon: "local_atm" },
{ label: "childComponent", text: "childComponent", icon: "notifications" },
].map(({ label, text, icon }, index) => (
<ListItem
component={RouterLink}
selected={pathname === `/${text}`}
to={`/${text}`}
button
key={text}
disabled={text !=='minhaConta' && !cadCompleto ? true : false}
onClick={() => {click(text) }}            
>
<ListItemIcon>
<Icon>{icon}</Icon>
</ListItemIcon>
<ListItemText primary={label.toUpperCase()} />
</ListItem>
))}
</List>
<Divider />
</div>
);
return(
...
{drawer}
...
)
...

App.js

...
export default function App() {
const childRef = useRef();
...
<Router>           
<AppBarAndDrawer/>
<Switch>
<Route path="/childComponent">
<childComponent />
</Route>
...
...

您创建的ref确实需要驻留在一个共同的祖先中,即App,因此它和一个回调可以传递给子组件。refChildComponent和回调到AppBarAndDrawer。此外,ChildComponent将需要使用useImperativeHandle钩子来公开子resetMyState的处理程序。

MeusAnuncios

使用useImperativeHandle钩子公开resetMyState处理程序。

const MeusAnuncios = forwardRef((props, ref) => {
const [myState, setMyState] = useState(null);

function resetMyState(){
setMyState(null);
}
useImperativeHandle(ref, () => ({
resetMyState,
}));
async function chargeMyState() {
await
...
setMyState(values)
...
}
...
});

应用

创建resetChildState回调,并将其传递给子组件,并将回调传递给AppBarAndDrawer组件。

export default function App() {
const childRef = useRef();
const resetChildState = () => {
if (childRef.current.resetMyState) {
childRef.current.resetMyState();
}
};
...
<Router>           
<AppBarAndDrawer onClick={resetChildState} /> // <-- pass callback
<Switch>
<Route path="/childComponent">
<ChildComponent ref={childRef} /> // <-- pass ref
</Route>
...
</Switch>
...
</Router>
}

AppBarAndDrawer

使用并调用传递的回调函数

const AppBarAndDrawer = ({ onClick }) => { // <-- destructure callback
...
const drawer = (
<div>
...
<List>
{[
...
].map(({ label, text, icon }, index) => (
<ListItem
component={RouterLink}
selected={pathname === `/${text}`}
to={`/${text}`}
button
key={text}
disabled={text !=='minhaConta' && !cadCompleto}
onClick={() => {
click(text);
onClick(); // <-- call callback here
}}            
>
<ListItemIcon>
<Icon>{icon}</Icon>
</ListItemIcon>
<ListItemText primary={label.toUpperCase()} />
</ListItem>
))}
</List>
...
</div>
);
...
};

最新更新