在React中,我如何从另一个组件调用一个组件中的函数(正在用React Router渲染)?



真的需要一些帮助来解决这个障碍。我有一个非常基本的React应用程序,我正在构建它有以下组件和结构:

App
Nav
Main
PageOne
PageOneDetail
...

我希望能够从组件结构中的任何组件调用Nav中的函数。到目前为止,我的理解是我可以用props来做这个。我知道如何使用子组件来实现它,但不确定如何使用孙子或兄弟组件来实现它。

我试图坚持功能组件和使用香草React,我使用React路由器渲染组件与路由。

这里是我的代码的简化版本:

App.js

import React, { Component } from 'react'
import Nav from './Nav'
import Main from './Main'

class App extends Component {
render() {
<Nav />
<Main />
}
}
export default App

Nav.js

import React from 'react'
import { NavLink } from 'react-router-dom'
const Nav = (props) => {

function doSomethingToNav() {
// here's where I want to change appearance or do whatever to the nav
// I want to be able to use this function from within my Nav component
// but also want to be able to call it from any another component
}
return(
<nav>
<NavLink to="/pageone">Page One</NavLink>
<NavLink to="/pagetwo">Page Two</NavLink>
</nav>
)
}
export default Nav

Main.js

import React from 'react'
import { Route, Switch } from 'react-router-dom'
import PageOne from './PageOne'
import PageOne from './PageTwo'
const Main = (props) => {
return (

<main>
<Switch>
<Route exact path='/pageone'><PageOne /></Route>
<Route exact path='/pagetwo'><PageTwo /></Route>
</Switch>
</main>
}   
export default Main

PageOne.js

import React, { Component } from 'react'
import { Switch, Route, BrowserRouter } from 'react-router-dom'
import SomeListOfItems from 'SomeListOfItems'
export default class PageOne extends Component {
render(){
<BrowserRouter>
<Switch>
<Route>
<SomeListOfItems />
</Route>
<Route path="/pageone/:number/" component={PageOneItem} />
// I also want to call the doSomethingToNav method when I route to the 
// PageOneItem component
</Switch>
</BrowserRouter>
}
}

PageOneItem.js

import React from 'react'
import { Link } from 'react-router-dom'

const PageOneDetail = (props) => {

return(
<div>
<Link to='/pageone'>Close</Link> 
// I want to call doSomethingToNav function when I close this component. 
// Close, in this case, is just routing back to /pageone
<p>Some content...</p>
</div>
)
}
export default PageOneDetail

您可以使用具有上下文的解决方案,并让所有包装组件使用useContext钩子访问它。

你可以这样使用它:

<<p>应用程序组件/strong>
import React, { Component, useState } from 'react';
import Nav from './Nav';
import Main from './Main';
const AppContext = createContext({
executeNavigationFunction: () => {},
setExecuteNavigationFunction: (navFunction: () => void) => {},
});
const App = () => {
const [executeNavigationFunction, setExecuteNavigationFunction] = useState(() => {});
return (
<AppContext.Provider value={{ executeNavigationFunction, setExecuteNavigationFunction }}>
<Nav />
<Main />
</AppContext.Provider>
);
};
export default App;
<<p>导航组件/strong>
import React, {useEffect, useContext, useEffect} from 'react';
import { NavLink } from 'react-router-dom';
import AppContext from 'app';
const Nav = (props) => {
const { setExecuteNavigationFunction } = useContext(AppContext);
function doSomethingToNav() {
// here's where I want to change appearance or do whatever to the nav
// I want to be able to use this function from within my Nav component
// but also want to be able to call it from any another component
}
useEffect(() => {
setExecuteNavigationFunction(doSomethingToNav)
}, [setExecuteNavigationFunction])
return (
<nav>
<NavLink to="/pageone">Page One</NavLink>
<NavLink to="/pagetwo">Page Two</NavLink>
</nav>
);
};
export default Nav;
<<p>PageOneItem组件/strong>
import React, {useEffect, useContext} from 'react';
import { Link } from 'react-router-dom';
import AppContext from 'app';
const PageOneDetail = (props) => {
const { executeNavigationFunction } = useContext(AppContext);
useEffect(() => {
executeNavigationFunction();
}, []);
return (
<div>
<Link to="/pageone">Close</Link>
// I want to call doSomethingToNav function when I close this component. // Close, in this case, is just routing
back to /pageone
<p>Some content...</p>
</div>
);
};
export default PageOneDetail;

通过这种方式,你可以在应用程序的任何部分使用应用程序的任何部分的任何数据。

这可能看起来有点粗糙,但如果你不使用全局状态库,Context是一种方法。

最新更新