Как я могу передать «имя пользователя» в качестве реквизита от функционального родителя без сохранения состояния к функциональному дочернему элементу без сохранения состояния другому дочернему элементу с сохранением состояния?

Как я могу передать username в качестве реквизита от функционального родителя без состояния к функциональному дочернему элементу без состояния другому дочернему элементу с сохранением состояния?

В настоящее время он показывает undefined как в первом дочернем, так и во втором дочернем элементе.

Родительский компонент:

  let userName = 'Some UserName';

  export default function App() {
   return (
    <Router>
  <div>
    <AuthButton />
    <Route path="/" render={() => (
      <Redirect to="/auth" />
    )} />
    <Route path="/auth" component={Login} />
    <PrivateRoute
      path='/home'
      component={Home}
      render={(props) => <Home userName={props.userName} />}
    />
  </div>
</Router>
 )
}  

Первый дочерний компонент:

 function Home(props) {

let userName = props.userName

console.log(userName);   // SHOWS UNDEFINED!

return (
    <Router>
        <div>
            <Header />
            <Switch>
                <div className="row cont">
                        <div className="card">
                            <div className="card-header">
                                Messages
                        </div>
                            <div className="card-body">
                                <MessengerApp userName={props.userName} />
                            </div>
                        </div>
                </div>
            </Switch>
            <Footer />
        </div>
    </Router >


   );
 }

Второй дочерний компонент:

class MessengerApp extends React.Component {
 constructor(props) {
    super(props);
   // set the initial state of the application
    this.state = { username: this.props.userName };

 console.log(this.state.username)  // SHOWS UNDEFINED!  

 }

 render(){
     // JSX
  }

Я хочу, чтобы все компоненты регистрировали имя пользователя как Some UserName


person Shahriar Firoz    schedule 05.02.2019    source источник


Ответы (2)


Вы неправильно передаете свойство UserName в Home из компонента приложения. Функция обратного вызова рендеринга для Route предоставляет реквизиты Router, а не реквизиты компонента.

let userName = 'Some UserName';

export default function App(props) {
   return (
    <Router>
        <div>
            <AuthButton />
            <Route path="/" render={() => (
              <Redirect to="/auth" />
            )} />
            <Route path="/auth" component={Login} />
            <PrivateRoute
              path='/home'
              component={Home}
              render={(routerProps) => <Home {...routerProps} userName={userName} />}
            />
          </div>
    </Router>
 )
}  
person Shubham Khatri    schedule 05.02.2019
comment
Спасибо, но я на самом деле нашел причину, по которой он не работал, и смог исправить. Пожалуйста, смотрите мой ответ. Кроме того, {props} должен работать, {routerProps} есть в React? Нигде не смог найти. - person Shahriar Firoz; 05.02.2019
comment
routerProps — это просто имя, позволяющее различать реквизиты компонентов и поставщика реквизитов маршрутизатором, вы можете назвать его как угодно. - person Shubham Khatri; 06.02.2019

Я действительно выяснил причину, по которой он не работал. Поскольку PrivateRoute был настроенным компонентом маршрута, он не распознавал render как метод передачи props. Мне пришлось переместить render props в фактический тег Route внутри этой функции PrivateRoute. Пожалуйста, смотрите ниже:

let userName = 'Some UserName';


  const PrivateRoute = ({ component: Component, ...rest }) => (
      <Route {...rest} render={(props) => (
       authFunc.isAuthenticated === true
          ? <Component {...props} userName={userName}/>
         : <Redirect to={{
           pathname: '/auth',
           state: { from: props.location }
          }} />
      )} />
     )

export default function App(props) {
   return (
    <Router>
        <div>
            <AuthButton />
            <Route path="/" render={() => (
              <Redirect to="/auth" />
            )} />
            <Route path="/auth" component={Login} />
            <PrivateRoute
              path='/home'
              component={Home}
            />
          </div>
    </Router>
 )
}
person Shahriar Firoz    schedule 05.02.2019