не удается передать значение родительскому компоненту react

#javascript #reactjs

#javascript #reactjs

Вопрос:

Я не могу передать значение от дочернего компонента родительскому компоненту. Я новичок в react, пожалуйста, направьте меня.

Это компонент приветствия —

 /* eslint-disable react/prop-types */
import React from "react";
const Greeting = props => {
  const isLoggedIn = props.isLoggedIn;
  const name = props.name;

  if (isLoggedIn) {
    return <h1> Welcome Back {name}</h1>;
  } else {
    return <LoginInfo name={name} onChange={props.onChange} />;
  }
};

function LoginInfo(props) {
  return (
    <div>
      <h1> Please Login</h1>
      <input type="text" value={props.name} onChange={props.onChange} />
    </div>
  );
}

export default Greeting;
  

Это компонент входа в систему —

 import React, { Component } from "react";
import Greeting from "./Greeting";
import LogoutButton from "./LogoutButton";
import LoginButton from "./LoginButton";

class Login extends Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {
      isLoggedIn: false,
      name: ""
    };
  }

  handleLoginClick() {
    this.setState({ isLoggedIn: true });
  }
  handleLogoutClick() {
    this.setState({ isLoggedIn: false });
  }
  onChange = e => {
    this.setState({
      name: e.target.value
    });
  };

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    const name = this.state.name;

    let button;

    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting
          isLoggedIn={isLoggedIn}
          name={name}
          onChange={this.onChange}
        />
        {button}
      </div>
    );
  }
}

export default Login;
  

Я использую в своем приложении.

 <Login />
  

В компоненте приветствия, как бы ни вводил пользователь, я могу сохранить в состоянии и отобразить в строке приветствия с именем.

Комментарии:

1. Откуда берутся name и this.handleChange in LoginInfo ?

2. Это будет пустое поле ввода, как только пользователь введет, мы отобразим.

3. Планируется ли здесь использовать API или вы просто хотите отобразить то, что введено в поле ввода?

4. @James Я просто пытаюсь отобразить то, что введено.

5. Данные в React передаются только одним способом — от родительского компонента к дочернему. Вы должны передавать ссылки на функции в качестве реквизита дочерним компонентам и сохранять определения функций в родительском — прочитайте это для более подробного объяснения .

Ответ №1:

Я думаю, вам нужно поддерживать состояние в вашем родительском компоненте и передавать событие изменения из дочернего компонента и изменять состояние в родительском. Нравится

В компоненте login

 nameChange = (e) => {
        this.setState({
          name: e.target.value
        })
    }

 <Greeting isLoggedIn={isLoggedIn} name={this.state.name} nameChange={this.nameChange}/>
  

и в дочернем

 <input
        type="text"
        name="name"
        value={this.props.name}
        onChange={this.props.nameChange}
      />
  

Комментарии:

1. Спасибо за ответ, даже я пытался сделать что-то подобное. передача значения состояния из родительского входа в дочернее приветствие. Можете ли вы увидеть в моем коде что-то неправильное, пожалуйста, укажите.

Ответ №2:

Итак, вот как я бы реорганизовал ваш код для LogInInfo компонента, чтобы передать значения пользователя вашему LogIn компоненту

Прежде всего, вам нужно состояние в LogInInfo поскольку вы хотите сохранить значения пользователя, вы будете использовать состояние для этого

 /* eslint-disable react/prop-types */
import React from "react";
const Greeting = props => {
  const isLoggedIn = props.isLoggedIn;

  if (isLoggedIn) {
    return <h1> Welcome Back</h1>;
  } else {
    return <LoginInfo submitForm={props.handleSubmitForm}/>;
  }
};

class LoginInfo extends React.Component {
  constructor(props) {
    this.state = {
      name: ""
    }
  }

  handleChange = (event) => {
    this.setState({ name: event.target.value })
  }
  render(){
    return (
      <div>
        <h1> Please Login</h1>
        // e is the event that is passed automatically to the function in onSubmit
        <form onSubmit={e => this.props.submitForm(e, this.state.name)}>
          <input
            type="text"
            name="name"
            value={name}
            onChange={this.handleChange}
          />
          <input type="submit" />
        </form>
      </div>
    );
  }
}

export default Greeting;
  

На данный момент у вас есть значение, которое вы хотите передать родительскому компоненту LogIn чтобы передать это значение, вам нужна функция в вашем родительском компоненте, которая получит это значение для вас и передаст его дочернему компоненту, чтобы его можно было использовать, мы сделаем это через props. Нам также нужна переменная в родительском состоянии, которая будет хранить это значение

 import React, { Component } from "react";
import Greeting from "./Greeting";
import LogoutButton from "./LogoutButton";
import LoginButton from "./LoginButton";

class Login extends Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {
      isLoggedIn: false,
      username: ""
    };
  }

  handleLoginClick() {
    this.setState({ isLoggedIn: true });
  }
  handleLogoutClick() {
    this.setState({ isLoggedIn: false });
  }
  // when you use arrow functions they automatically bind to your component

  handleSubmitForm = (e, value) => {
    // the following line prevents the page from refreshing when you submit any form
    e.preventDefault()
    this.setState({ username: value })
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;

    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} submitForm={this.submitForm}/>
        {button}
      </div>
    );
  }
}

export default Login;
  

когда вы нажимаете кнопку отправки, это должно обновить состояние в LogIn компоненте. Надеюсь, это поможет

Комментарии:

1. Спасибо Дэвиду за ответ

Ответ №3:

Вам нужно сделать 2 вещи:

  1. создайте функцию, которая будет обрабатывать изменения ввода в компоненте Login, отправьте его в приветствие, а затем в LoginInfo. функция будет выглядеть примерно так:
    onChange = (event) => this.setState({event.target.name: event.target.value})

    примечание: event.target.name равно реквизиту имени ввода. описанная выше функция будет работать, только если имя состояния, в котором хранится это входное значение, равно имени ввода, в вашем случае name.

  2. отправьте состояние, в котором хранится значение ввода, в LoginInfo. входной элемент должен выглядеть следующим образом:
    <input type="text" name="name" value={valueFromLogin} onChange={props.onChangeFromLogin} />