Эта статья первоначально появилась на https://vahid.blog.

Допустим, ваше приложение React имеет интеллектуальный компонент (т. е. компонент имеет свое собственное состояние), и вы хотите, чтобы дочерний компонент мог не только получать доступ, но и фактически изменять состояние этого родительского компонента.

Как вы можете дать дочернему компоненту эту функциональность?

  1. Определите эту функцию изменения состояния в родительском компоненте.
  2. Передайте эту функцию дочернему компоненту в качестве реквизита.
  3. Иметь триггер внутри дочернего компонента, который вызывает эту функцию

Вот пример.

У нас есть компонент App, состояние которого включает blogs (массив) и searchfield (строку).

Мы хотим, чтобы дочерний компонент SearchBox мог обновлять строку searchfield.

1. Определите функцию в родительском компоненте

Наш первый шаг — определить функцию onSearchChange внутри определения класса App.

Эта функция принимает событие в качестве аргумента и обновляет searchfield целевым значением этого события.

class App extends React.Component {
  constructor(){
    super();
    this.state = {
      blogs: [],
      searchfield: ''
    };
  }
  onSearchChange = (event) => {
    this.setState({searchfield: event.target.value});
  }
}

2. Передайте эту функцию как реквизит

Затем, все еще внутри компонента App, нам нужно передать onSearchChange в качестве реквизита при рендеринге нашего дочернего компонента SearchBox.

render(){
    return (
      <div className = 'tc'>
        <h1>My blog posts</h1>
        <SearchBox onSearchChange={this.onSearchChange} />
        <BlogDisplay blogs= { filteredBlogs } />
      </div>
    )
  }

3. Включите триггер внутри дочернего компонента, который вызывает эту функцию.

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

Это весь наш компонент SearchBox:

import React from 'react';
const SearchBox = ({onSearchChange}) => {
  
  return (
    <div className='pa2'>
      <input
      type="search" 
      placeholder="search blogs"
      onChange={onSearchChange}
      /> 
    </div>
  )
}
export default SearchBox;

Обратите внимание, что выше мы использовали деструктурирование объекта для извлечения ключа onSearchChange из объекта props.

Мы также могли бы сделать следующее, что делает то же самое:

import React from 'react';
const SearchBox = (props) => {
  
  return (
    <div className='pa2'>
      <input 
      type="search" 
      placeholder="search blogs"
      onChange={props.onSearchChange}
      /> 
    </div>
  )
}
export default SearchBox;