简体   繁体   English

如何将一个函数从 Parent 传递给 React.js 中的路由中的元素?

[英]How to pass a function from Parent to an element within a route in React.js?

I want to pass a function to a component through a Route , I can do it with direct children but when it comes to Routes i can't figure it how to do it.我想通过 Route 将函数传递给组件,我可以使用直接子级来完成,但是当涉及到 Routes 时,我不知道该怎么做。

look at the code below , i want to pass "updateUserState" function to Profile Component , the function works properly in Header component but it's not working in Profile component which lives inside the Routes .看看下面的代码,我想将“updateUserState”函数传递给 Profile 组件,该函数在 Header 组件中正常工作,但在位于 Routes 内的 Profile 组件中不起作用。

class App extends React.Component {  

  updateUserState = (currentUser) => {
    if(currentUser != null) {
      this.setState({
        currentUser: currentUser
      })
    } else {
      this.setState({
        currentUser: null
      });
    }
    return this.state.currentUser;
  }
  
  render() {
    return (
      <div className="App">
        <Header updateUserState={this.updateUserState} />
        <Routes>
          <Route path='/profile' element={<ProfilePage updateUserState={this.updateUserState} />}/>
        </Routes>
      </div>  
    );
  }
}

this is the code in Profile component which is completely similar to Header Component :这是 Profile 组件中的代码,与 Header 组件完全相似:

const ProfileCard = ({updateUserState}) => {  
   const signout = () => {
      handleLogout()
      updateUserState()
   }
   return (
      <div className='profile-card'>
         <a onClick={() => signout()}>
            Sign Out 
         </a>  
      </div>
   )
}

Update : solved thanks to Abir Taheer !更新:感谢Abir Taheer解决!

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      currentUser: null
    }  

    this.updateUserState = this.updateUserState.bind(this);
  }


  updateUserState = (currentUser) => {
    if(currentUser != null) {
      this.setState({
        currentUser: currentUser
      }, () => console.log(this.state.currentUser))
    } else {
      this.setState({
        currentUser: null
      }, () => console.log(this.state.currentUser));
    }
    return this.state.currentUser;
  }
  
  render() {
    return (
      <div className="App">
  
        <Header currentUser={this.state.currentUser} updateUserState={this.updateUserState} />
        <Routes>
          <Route path='/profile' element={<ProfilePage updateUserState={this.updateUserState}
          currentUser={this.state.currentUser} />}
          />
        </Routes>

        
      </div>  
    );
  }
}

then inside ProfilePage :然后在 ProfilePage 内:


const ProfilePage = ( {currentUser, updateUserState} ) => {
   return (
      <div>{
            currentUser ? 
            <div>
               <ProfileCard id={currentUser.id} updateUserState={updateUserState} />
            </div>
            :
            <h1>No User Signed In</h1>
      }</div>
   )
}

And ProfileCard :和 ProfileCard :

const ProfileCard = ({id, updateUserState}) => {
   
   const signout = () => {
      handleLogout()
      updateUserState();
   }

   return (
      <div className='profile-card'>
         <a onClick={() => signout()}>
            Sign Out 
         </a>  
      </div>
   )
}

The way you do it seems like you are rendering the component instead of passing a reference.您这样做的方式似乎是在渲染组件而不是传递引用。

How I would suggest is to wrap the component in another function and return with your function passed in as a prop.我建议的方法是将组件包装在另一个函数中,然后返回作为道具传入的函数。 So basically making another react component with the method passed in. Use that wrapper component instead:所以基本上用传入的方法制作另一个反应组件。改用那个包装器组件:

const wrappedProfilePage = () => <ProfilePage updateUserState={this.updateUserState} />;

..
.
.

 <Route path='/profile' element={wrappedProfilePage}/>


The issue arises because of the this keyword.问题是由于this关键字而出现的。 When you're passing a function to another component you need to bind the this keyword to the parent instance otherwise it may not work properly.当您将函数传递给另一个组件时,您需要将this关键字绑定到父实例,否则它可能无法正常工作。

This behavior is described in the React Docs here: https://reactjs.org/docs/faq-functions.html此行为在此处的 React 文档中进行了描述: https ://reactjs.org/docs/faq-functions.html

and more specifically further down in the page here: Why is binding necessary at all?更具体地说,在页面的下方: 为什么需要绑定?

When you bind this to the parent instance then it refers to the correct state and the function should work.当您将this绑定到父实例时,它会引用正确的状态并且该函数应该可以工作。

You need to update your component like such:您需要像这样更新您的组件:

class App extends React.Component {
  constructor(props) {
    super(props);

    // Make sure to initialize your state accordingly
    this.state = {
      currentUser: null,
    };

    // --- This is the line you need ---
    this.updateUserState = this.updateUserState.bind(this);
  }

  updateUserState(currentUser) {
    if (currentUser != null) {
      this.setState({
        currentUser: currentUser,
      });
    } else {
      this.setState({
        currentUser: null,
      });
    }
    return this.state.currentUser;
  }

  render() {
    return (
      <div className="App">
        <Header updateUserState={this.updateUserState} />
        <Routes>
          <Route
            path="/profile"
            element={<ProfilePage updateUserState={this.updateUserState} />}
          />
        </Routes>
      </div>
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM