Реакция - изменение состояния от внешнего компонента - PullRequest
0 голосов
/ 24 апреля 2020

Я знаю, что задам вопрос, который нарушает некоторые правила о базовом / базовом c способе использования React ... но, возможно, в этом примере кто-то поможет мне решить проблему, с которой я столкнулся.

Это не полный код моего проекта, но точно показать идею моей проблемы:

https://codesandbox.io/s/change-state-from-external-component-zi79e

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

Существует ли способ достичь этого? В моем проекте у меня есть родитель, который создает несколько родовых c потомков, и будет сложнее обработать этот запрос.

И, в частности, мне нужно изменить состояние одного потомка (MyFirstChild) после того, как другой ребенок (SecondChild) прочитал нажатие клавиши и запустил API, чтобы получить некоторые значения из моего бэкэнда; после этого мне нужно отправить изменение в «MyFirstChild», чтобы изменить его состояние. Родительский компонент имеет ~ 50 дочерних компонентов, и я заблокировал метод повторного рендеринга (с помощью метода shouldComponentUpdate)

Ожидаемый ответ: «Это невозможно, или вы нарушили правильное использование React» ...

Но, возможно, использование forwardRef или ref или что-то еще, чего я не вижу, может помочь мне обойти это ...

Ответы [ 3 ]

2 голосов
/ 24 апреля 2020

Чтобы изменить состояние дочернего компонента от родительского без запуска метода рендеринга (в родительском): одним из возможных решений было бы использование Redux. С помощью Redux от родителя вы можете отправить действие (выполнить действие, которое изменяет состояние Redux). А в дочернем компоненте вы получаете ту часть состояния, которую вы изменяете (это может быть строка, объект и т. Д. c) в качестве реквизита. Поэтому, когда он будет изменен по сравнению с родительским, ваш дочерний компонент будет визуализироваться снова без необходимости запуска метода рендеринга в родительском.

https://react-redux.js.org/introduction/basic-tutorial

Вы также можете используйте Context для той же цели.

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

Если вы хотите изменить вещи из родительского, без повторного рендеринга с Redux, это будет примерно так:

у родителя

const changeTitle = (newTitle) => {
  this.props.setTitle(newTitle);
}

return (
<div className="App">
  <ChildComponent />
</div>
);

const mapDispatchToProps = dispatch => ({
  setTitle: newTitle => dispatch(setTitleACTION(newTitle)),
});

у ребенка

return (
      <div>
        <h1>
          {this.props.title}
        </h1>
        <h2>Start editing to see some magic happen!</h2>
      </div>
    );

const mapStateToProps = ({ title }) => ({
  title,
});

export default connect(mapStateToProps, null)(ChildComponent);

Снова, если вы сделаете в случае с Redux вы можете получить реквизит title из хранилища Redux , а в родительском вы измените эту переменную (вызывая действие Redux) без повторной визуализации родителя.

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

0 голосов
/ 24 апреля 2020

На основе объяснения @david paley ...

Если единственный способ добиться этого - использовать Redux, я выкладываю свое решение (Это тот же пример, но реализующий Redux) ... надеюсь, что это работает для всех остальных.

https://codesandbox.io/s/change-state-from-external-component-redux-rmzes?file= / src / App. js

0 голосов
/ 24 апреля 2020

Разве мы не можем использовать здесь реквизиты для передачи данных вместо попыток манипулировать состоянием извне компонента?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...