Reactjs 更新祖父母状态

Posted

技术标签:

【中文标题】Reactjs 更新祖父母状态【英文标题】:Reactjs update grandparent state 【发布时间】:2020-03-07 18:48:03 【问题描述】:

我刚刚开始使用 ReactJs 进行开发,并且一直在关注 serverless-stack.com 教程。我已准备好扩展应用程序并创建一个包含 n 个子组件的模板,但在管理孙子组件之间的用户会话时遇到了问题。

我有管理用户会话的 App.js。但是我在孙子组件中有我的退出按钮,我无法让它调用 App.js 的 signOut() 函数。

App.js

function App(props) 
  const [isAuthenticating, setIsAuthenticating] = useState(true);
  const [isAuthenticated, userHasAuthenticated] = useState(false);

  useEffect(() => 
    onLoad();
  , []);

  const onLoad = async () => 
    try 
      await Auth.currentSession();
      userHasAuthenticated(true);
     catch (e) 
      if (e !== "No current user") 
        alert(e);
      
    
    setIsAuthenticating(false);
  

  const signOut = async () => 
    console.log("Signing out.");
    await Auth.signOut();
    userHasAuthenticated(false);
    console.log("signed out.");
  ;

  return (
    <BrowserRouter>
        <Switch>
...
          <Layout
            path='/'
            name='Home'
            ...props
            onLogout=signOut
          />
        </Switch>
    </BrowserRouter>
  );


export default withRouter(App);

我的布局组件有一堆不同的组件,例如页眉、页脚、导航等。

function Layout(props) 
  return (
    <div className='app'>
...// header component
          <NavBar
            onLogout=props.onLogout
            isAuthenticated=props.isAuthenticated
          />
... //main body and footer components
</div>
);

export default Layout;

最后是我的 NavBar 孙子组件:

function NavBar(props) 
  useEffect(() => 
    onLoad();
  , []);

  async function onLoad() 
    console.log("Is authed at navbar? " + props.isAuthenticated);

  

  return (
    <React.Fragment>
      <Nav className='ml-auto' navbar>
.. // other NavItems
        <UncontrolledDropdown nav direction='down'>
          <DropdownToggle nav>
            <img
              src="../../assets/img/usermenu.png"
              className='img-avatar'
              alt='user menu icon'
            />
          </DropdownToggle>
          <DropdownMenu right>
...
            <DropdownItem onClick=props.onLogout>
              <i className='fa fa-lock'></i> Logout
            </DropdownItem>
          </DropdownMenu>
        </UncontrolledDropdown>
      </Nav>
    </React.Fragment>
  );


export default NavBar;

当我加载站点并进行身份验证时,控制台会写出“在导航栏上进行身份验证?是的”。所以我知道孙子正确地获得了isAuthenticated 状态。但是当我单击注销按钮时,没有任何反应,控制台中也没有出现警告或错误。

【问题讨论】:

【参考方案1】:

一开始在Navbar组件中看到了这个功能

async function onLoad() 
    console.log("Is authed at navbar? " + props.isAuthenticated);

我跟踪查看您从哪里通过props.isAuthenticated。我确实在这里找到了它

<Layout
  path='/'
  name='Home'
  props=props
  onLogout=signOut
/>

为什么你有一个叫props的道具???如果您想将传递给父级的所有道具传递给其子级(传输道具),请使用spread operator。你可以在这里看到答案:What does it mean ...rest in React JSX

【讨论】:

在我测试它们是否正确传递时更重要。我已经更新了这个问题。但这对从孙子组件调用祖父函数没有任何影响。 这样试试。 onClick=()=&gt;props.onLogout 1.你能console.log(props.onLogout) 确保onLogout 不是未定义的。 --- 2.你能不能把&lt;DropdownItem onClick=props.onLogout&gt;改成&lt;DropdownItem onClick=()=&gt;console.log('onClick works')&gt;来验证回调是否真的被调用了。

以上是关于Reactjs 更新祖父母状态的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS 从孩子更新状态

当孩子必须更新父母的状态时,this.setState 不起作用

如何使用reactjs解析从孩子到父母的数据?

通过 Parent 传递的 prop 获取子组件的当前状态 - Reactjs

ReactJS 从子类更改另一个类的状态

如何确保更新 reactjs 状态,然后调用函数?