React — Как изменить реквизиты дочернего компонента при возникновении события?

#javascript #reactjs #components

#javascript #reactjs #Компоненты

Вопрос:

У меня есть компонент под названием Nav. Я хочу отправлять реквизиты другому компоненту, называемому Body, когда пользователь использует типы в строке поиска. Проблема, с которой я сталкиваюсь, заключается в том, что значение в компоненте Body не меняется при вводе в строке поиска.

Класс Nav:

 constructor(props) {
  super(props);
  this.state = { id: "" };

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

handleChange = event => {
  this.setState({ id: event.target.value });
};

render() {
  return (
    <div>
      <nav className="navbar navbar-expand-lg navbar-dark bg-dark">
        <button
          className="navbar-toggler"
          type="button"
          data-toggle="collapse"
          data-target="#navbarTogglerDemo03"
          aria-controls="navbarTogglerDemo03"
          aria-expanded="false"
          aria-label="Toggle navigation"
        >
          <span className="navbar-toggler-icon" />
        </button>

        <a className="navbar-brand" href="#">
          <img src="https://icon-icons.com/icons2/1412/PNG/48/comics-spiderman-cam_97492.png" />
          Home
        </a>

        <div className="collapse navbar-collapse" id="navbarTogglerDemo03">
          <ul className="navbar-nav mr-auto mt-2 mt-lg-0">
            <li className="nav-item active">
              <a className="nav-link" href="#">
                <span class="sr-only">(current)</span>
              </a>
            </li>
            <li className="nav-item">
              <a className="nav-link" href="#">
                Link
              </a>
            </li>
            <li className="nav-item">
              <a
                className="nav-link disabled"
                href="#"
                tabindex="-1"
                aria-disabled="true"
              >
                Disabled
              </a>
            </li>
          </ul>
          <form
            className="form-inline my-2 my-lg-0"
            onSubmit={() => {
              console.log(this.state.id);
            }}
          >
            <input
              className="form-control mr-sm-2"
              type="search"
              placeholder="Search"
              aria-label="Search"
              value={this.state.id}
              onChange={this.handleChange}
            />
            <button className="btn btn-light" type="submit">
              Search
            </button>
          </form>
        </div>
      </nav>
      <Body valorId={this.state.id} />
      {alert(this.state.id)}
    </div>
  );
}
  

Класс body:

 constructor(props) {
  super(props);
  this.state = { heroe: null, loading: true };
}

async componentDidMount() {
  const url = "https://superheroapi.com/api/2132321/"   this.props.valorId;
  console.log("aca va:"   this.props.valorId);
  alert(url);
  const response = await fetch(url);
  const data = await response.json();
  console.log(data.name);
  this.setState({ heroe: data, loading: false });
}
  

Спасибо.

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

1. Привет, проблема в том, что вы используете componentDiMount. он будет выполняться один раз, как только компонент будет загружен. Вы можете использовать другую функцию в качестве componentWillUpdate или Getderivedstate from Props

2. Привет, спасибо за комментарий. Теперь я пытаюсь

3. WillMount и DidMount — это практически одно и то же, они выполняются один раз при монтировании компонента (они не просто выполняются одновременно)

4. Я использовал componentWillUpdate, и это сработало!! большое вам спасибо.

5. @Tholle опубликует хороший ответ таким образом. вы должны посмотреть на это 😉 установите это как «ответ», если это вам поможет

Ответ №1:

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

Пример

 class Body extends React.Component {
  constructor(props) {
    super(props);
    this.state = { heroe: null, loading: true };
  }

  componentDidMount() {
    this.loadHeroe();
  }

  componentDidUpdate(prevProps) {
    if (this.props.valorId !== prevProps.valorId) {
      this.loadHeroe();
    }
  }

  loadHeroe = async () => {
    this.setState({ loading: true });

    const url = "https://superheroapi.com/api/2132321/"   this.props.valorId;
    const response = await fetch(url);
    const data = await response.json();

    this.setState({ heroe: data, loading: false });
  };

  render() {
    // ...
  }
}
  

Ответ №2:

Проблема в том, что вы используете componentDidMount Эта функция вызывается один раз, при монтировании компонента.

Попробуйте использовать componentDidUpdate вместо