Передача данных между компонентами родитель-ребенок
Всем привет. Ситуация следующая. У меня есть два компонента: Header и Searchbox. Searchbox представляет из себя input tupe = "serchbox", в который я ввожу текстовую информацию. Компонент Header является родителем для Searchbox. Т.е. я рендерю searchbox внутри Header. Мне надо, чтобы информация которая была введена в input, который является передавалась в state компонента . Т.е. если более глобально, то есть шапка сайта, в ней input, в котором можно что-то вводить и эти данные должны сохраняться в state родительского компонента . Вот мой код. Компонент Searchbox
import React, { Component } from "react";
import "./style.scss";
class Searchbox extends Component {
constructor(props) {
super(props);
this.state = { name: "", requestResult: null };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
event.preventDefault();
this.setState({ name: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
// this.setState({ name: "" });
console.log(this.state.name);
}
render() {
const { requestResult, name } = this.state;
return (
<>
<form
id="search_movie"
className="search-movie"
onSubmit={this.handleSubmit}
>
<input
type="search"
value={name}
onChange={this.handleChange}
requestvalue={requestResult}
/>
</form>
<button
onClick={name => {
this.props.getData(name);
}}
>
OK
</button>
</>
);
}
}
export default Searchbox;
Компонент Header
import React, { Component } from "react";
import Searchbox from "../Searchbox";
import User from "../User";
import "./style.scss";
class Header extends Component {
constructor(props) {
super(props);
this.state = { name: "" };
}
getData = value => {
this.setState({ name: value });
console.log(this.state);
console.log(value);
};
render() {
return (
<div className="movie-header">
<div className="container">
<div>Movie Catalog</div>
<Searchbox getData={value => this.getData(value)} />
<User />
</div>
</div>
);
}
}
export default Header;
При клике на кнопке "OK" должна срабатывать функция getData(value), которая должна записать значение value в state компонента Header. Почему в моем случае этого не происходит? Вот ссылка на оригинал https://codesandbox.io/s/zealous-villani-u4rsm
Ответы (1 шт):
Проблема кроется в методе обработки клика на кнопку OK вот тут:
onClick={name => {
this.props.getData(name);
}}
Если вдуматься в смысл, то вы передаете не name вовсе, а event. То есть, нужен обработчик на клик, к примеру такой:
onOkClick = () => {
const { name } = this.state;
this.props.getData(name);
};
Тут мы достаем из стейта введенное name и отдаем нашему родителю в метод getData. Этот метод укажем в качестве обработчика для кнопки OK:
<button onClick={this.onOkClick}>OK</button>
Пример кода (на основании вашего) прилагаю тут:
class Searchbox extends React.Component {
constructor(props) {
super(props);
this.state = { name: "" };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
event.preventDefault();
this.setState({ name: event.target.value });
}
handleSubmit(event) {
event.preventDefault();
// this.setState({ name: "" });
console.log(this.state.name);
}
onOkClick = () => {
const { name } = this.state;
this.props.getData(name);
};
render() {
const { requestResult, name } = this.state;
return (
<div>
<form
id="search_movie"
className="search-movie"
onSubmit={this.handleSubmit}
>
<input
type="search"
value={name}
onChange={this.handleChange}
requestvalue={requestResult}
/>
</form>
<button
onClick={this.onOkClick}
>
OK
</button>
</div>
);
}
}
class Header extends React.Component {
constructor(props) {
super(props);
this.state = { name: "" };
}
getData = value => {
this.setState({ name: value });
console.log(this.state);
console.log(value);
};
render() {
return (
<div className="movie-header">
<div className="container">
<div>Movie Catalog</div>
<Searchbox getData={value => this.getData(value)} />
</div>
</div>
);
}
}
ReactDOM.render(
<Header />,
document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<!-- The content rendered into this tag should match the content below. -->
<div id="app"></div>
В качестве дополнения к ответу, советую обратить внимание на следущий код, написанный вами:
getData = value => {
this.setState({ name: value });
console.log(this.state);
console.log(value);
};
Так как метод setState добавляет в очередь изменения в состоянии компонента, то при выводе значения через console.log(this.state); после вызова setState вы не увидите своего значения в полученном результате. Думайте о setState(), как о запросе, а не как о команде немедленного обновления компонента. Можно использовать колбэк вторым параметром в методе setState, чтобы точно получить установленное значение в стейте, например вот так:
getData = value => {
this.setState({ name: value }, () => { console.log(this.state); });
console.log(value);
};