渲染 child 组件时触发 parent 组件的重新渲染

Trigger a rerender of parent component when a child component is rendered

我正在使用以下 material-ui 主题 Paperbase 并且在 Header.js 组件中,我有以下 useEffect 挂钩:

const [temperature, setTemperature] = useState([]);

  const getTemperature= async () => {
    try {

      const response = await fetch('/get-temperature')
      const tempData = await response.json();

      setTemperature(tempData);
    } catch (err) {
      console.error(err.message);
    }
  };

useEffect(() => {
    getTemperature();
}, []);  

这样做的主要目的是在 header 组件中显示当前温度作为信息,该组件显示在第一页 load/render。

现在在下面的 App.js 中,我有以下 return 设置,其中调用了上面的 Header 组件。

return (
    <Router>
      <UserProvider myinfo={myinfo}>
        <Switch>
          <Route path="/">
              <ThemeProvider theme={theme}>
                <div className={classes.root}>
                  <CssBaseline />
                  <nav className={classes.drawer}>
                    <Hidden xsDown implementation="css">
                      <Navigator />
                    </Hidden>
                  </nav>
                  <div className={classes.app}>
                    <Header
                      onDrawerToggle={handleDrawerToggle}
                    />
                    <main className={classes.main}>
                      <Switch>
                        <Route exact path="/new-user"
                          render={(props) => <Content key={props.location.key} />}
                        />
                        <Route exact path="/view-results"
                          render={(props) => <ViewResults key={props.location.key} />}
                        />
                      </Switch>
                    </main>
                  </div>
                </div>
              </ThemeProvider>
          </Route>
        </Switch>
      </UserProvider>
    </Router>
);

我的问题是,每当用户路由到 /new-user/view-results 时,我如何触发 Header (parent) 的重新呈现,而后者又调用Content.jsViewResults.js,为了让Header.js中的useEffect刷新数据,从RESTapi获取并显示[=46中的最新温度=] 又一次?

理想情况下,在呈现 Content.jsViewResults.js 时,确保调用 Header.js getTemperature()

如有任何帮助,我们将不胜感激。

您当前的代码非常接近多布局系统。作为 Route 的子组件,您可以通过 useLocation() 甚至本机 window.location.pathname.

访问当前位置

这是我的多布局 React 应用示例。您可以尝试使用它来适配您的代码。

MainLayout 在未指定 path 时使用回退路由。它还包含一个 Header 并包含一个页面

const Dispatcher = () => {
    const history = useHistory();

    history.push('/home');

    return null;
};

const App = () => (
    <BrowserRouter>
        <Switch>
            <Route
                component={Dispatcher}
                exact
                path="/"
            />

            <Route
                exact
                path="/login/:path?"
            >
                <LoginLayout>
                    <Switch>
                        <Route
                            component={LoginPage}
                            path="/login"
                        />
                    </Switch>
                </LoginLayout>
            </Route>

            <Route>
                <MainLayout>
                    <Switch>
                        <Route
                            component={HomePage}
                            path="/home"
                        />
                    </Switch>
                </MainLayout>
            </Route>
        </Switch>
    </BrowserRouter>
);

这里是 MainLayout

的代码

const MainLayout = ({ children }) => (
    <Container
        disableGutters
        maxWidth={false}
    >
        <Header location={props.location} />

        <Container
            component="main"
            maxWidth={false}
            sx={styles.main}
        >
            {children}
        </Container>

        <Footer />
    </Container>
);

现在 Header 可以是任何东西。您需要在此组件中放置一个捕获

import { useLocation } from 'react-router-dom'

cont Header = (props) => {
  const { pathname } = useLocation();
  
  //alternatively you can access props.location
  
  useEffect(() => {
    if (pathname === '/new-user') {
      getTemperature();
    }
  }, [pathname]);  
};

请注意,Header 不是 Route 的直接后代,因此它无法通过 props 直接访问该位置。您需要链上转账

Route -> MainLayout -> Header

或者更好地使用useLocation