Совместное использование состояния среди подкомпонентов в React - PullRequest
1 голос
/ 23 апреля 2020

В настоящее время я занимаюсь разработкой приложения , которое использует React в некоторых частях своего пользовательского интерфейса для реализации некоторых сложных интерактивных функций. Некоторые из этих частей приложения, которые на самом деле являются компонентами React, стали очень сложными по размеру.

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

Как вы можете себе представить, это становится неким беспорядком.

// MyComponent.js
class MyComponent extends React.Component  {
  constructor(props) {
    super(props);

    this.state = {
      list: [1, 2, 3, 4],
      selected: '',
    }

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

  add() {
    const newNumber = this.state.list[this.state.list.length - 1] + 1,
    list = [...this.state.list, newNumber]
    this.setState({list})
  }

  handleChange({target}) {
    this.setState({
      selected: target.value,
    })
  }

  render() {
    return (
        <>
          <List items={this.state.list} selected={this.state.selected} />
          <Button onClick={this.add} />
          <input type="text" value={this.state.selected} onChange={this.handleChange} />
        </>
      )
  }
}
// Button.js
class Button extends React.Component {
    render() {
        return (
            <button onClick={this.props.onClick}>Click me!</button>
        );
    }
}

// List.js
class List extends React.Component {

    constructor(props) {
        super(props)

        this.refs = props.items.map(_ => React.createRef())
    }

    render() {
        return (
            <ul>
                {this.props.items.map((item, key) =>
                    (<li ref={this.ref[key]} key={key}>{item}</li>)
                )}
            </ul>
        );
    }
}

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

Я провел некоторое исследование по inte rnet, и оказалось, что это очень распространенная проблема. На большинстве сайтов рекомендуется использовать Redux или другую библиотеку управления состоянием. Тем не менее, все учебники и руководства, которые я видел, которые реализуют Redux с React, похоже, предполагают, что вы используете только React для создания своего приложения в виде одностраничного приложения. Это не мой случай.

Есть ли способ поделиться состоянием компонента, чтобы избежать такого рода проблем? Есть ли, может быть, способ использовать Redux несколько раз для нескольких компонентов в одном приложении , где один магазин сохраняет только состояние для MyComponent и может быть доступен либо List, либо любым из его возможные дети?

Ответы [ 2 ]

2 голосов
/ 23 апреля 2020
  1. Redux не требует, чтобы весь ваш сайт был в React. Он реализует компонент более высокого уровня, который можно использовать с любыми компонентами React, даже если они встроены в другой сайт.

  2. Вы можете посмотреть на ловушки React для решения аналогичных проблем. В частности, проверьте useContext() и useState().

1 голос
/ 23 апреля 2020

В вашем примере вы использовали шаблон подъема состояния в реакции.

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

В этом случае вам нужно проверить redux с отдельным хранилищем или useContext () hook.

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