Реакция: установка состояния в контейнере из функционального компонента

#javascript #reactjs #components

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

Вопрос:

Итак, у меня есть компонент контейнера, который отображает функциональный компонент вместе с некоторыми другими JSX. Я пытаюсь изменить состояние в этом контейнере с помощью нажатия кнопки, которое происходит внутри этого функционального компонента. Однако я еще не нашел хорошей статьи по решению этой проблемы, и я сталкиваюсь с проблемой this.setState() is not a function или я полностью прерываю текущую вкладку, пытаясь trigger a setState call during a render (более или менее).

Вот несколько примеров кода, иллюстрирующих, что я имею в виду:

 class TestComponent extends Component {
  render() {
    <div>
      <FunctionalComponent close={(type) => this.setState({ property: type })} />
    </div>
  }
};
 

Функциональный компонент:

 const FunctionalComponent = (props) => {
  return (
    <button onClick={props.close('stringvalue')}>Click to setState</button>
  );
};
 

Также пытались создать отдельную функцию внутри контейнера и вызвать this.setState() оттуда, но проблема сохраняется. Это проблема контекста?

Ответ №1:

Немного больше идиоматики . . .

 class TestComponent extends Component {
  constructor(props) {
    super(props);
    this.onClose = this.onClose.bind(this);
  }

  onClose(property) {
    this.setState({ property })
  }

  render() {
    return (
      <div>
        <FunctionalComponent close={this.onClose} />
      </div>
    )
  }
};

const FunctionalComponent = ({ close }) => {
  return (
    <button onClick={close.bind(null, 'stringvalue')}>Click to setState</button>
  );
};
 

Ответ №2:

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

Для onClick требуется функция.

 const FunctionalComponent = (props) => {
  function onClick() {
    props.close('stringvalue');
  }
  return (
   <button onClick={onClick}>Click to setState</button>
  );
};
 

или

 const FunctionalComponent = (props) => {
  return (
   <button onClick={() => props.close('stringvalue')}>Click to setState</button>
  );
};