Совместное использование контента между смежными компонентами, HOC? - PullRequest
0 голосов
/ 22 февраля 2019

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

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

Создание контента внутри контейнера неосуществимо, потому что существует так много разных вариантов того, какой контент можно создать.В кодовой базе, над которой я работаю, есть 30-40 возможных компонентов, которые генерируют разное содержимое.

Я довольно новичок в React, поэтому у меня возникают трудности при попытке решить эту проблему способом реагирования.Я кратко прочитал про рендер реквизит / HOCs, может быть, это то, что мне нужно здесь?Любая помощь будет принята с благодарностью.

Вот очень простой пример того, как это выглядит: https://codesandbox.io/s/zqo2p1yy9m

Ответы [ 3 ]

0 голосов
/ 22 февраля 2019

Я согласен с victor.ja, но мне было интересно, есть ли у вас глобальный магазин, такой как Редукс.Затем вы можете просто вызвать действие, чтобы обновить состояние хранилища из верхнего компонента.Компонент высшего порядка может получить состояние магазина в качестве реквизита и обновить нижний компонент.

0 голосов
/ 22 февраля 2019

Существует несколько способов решения этой проблемы

1) Вы можете использовать систему управления состоянием, такую ​​как Redux, mobx, или вы можете использовать контекстный API React https://reactjs.org/docs/context.html. ОДНАКО, так как выЯ новичок в React, я бы посоветовал не заниматься этими правильными знаниями, пока вы не освоитесь с базовым потоком

2) Вы можете реализовать простой parent-child relationship для передачи данных между компонентами.В конце концов, это позволит вам обеспечить связь между смежными (одноуровневыми) компонентами.Как уже говорилось, этот поток обычно называется поднятием состояния.На самом деле системы государственного управления работают аналогичным образом.Позвольте мне объяснить эту логику, также принимая во внимание ваш пример сценария на основе сценария.

У нас будет компонент Контейнер.Этот компонент будет компонентом с состоянием.Единственная цель этого компонента-контейнера - иметь собственное целостное состояние, которое будет рассматриваться его источником как истина.Наличие нескольких методов для определения способов обновления этого целостного состояния.Дочерние компоненты будут чистыми компонентами или репрезентативными компонентами.Это означает, что у них не будет своих собственных государств.Они будут либо использоваться для отображения данных, которые им передает их родитель, либо для запуска методов, определенных их родителями, для обновления источника состояния истины.

У нас будет два сценария: В сценарии 1 список содержимого будет представлен как есть.В сценарии 2 список содержимого будет представлен в обратном порядке букв

class Container extends React.PureComponent {
  state = {
    reversed: false,
    newContent: "",
    contents: [
      {
        id: 1,
        text: "Initial Content"
      }
    ]
  };

  handleReverse = () => {
    this.setState((state) => ({
      ...state,
      reversed: !state.reversed
    }))
  }
  submitNewContent = () => {
    this.setState(state => ({
      ...state,
      contents: [
        ...state.contents,
        { id: Math.random(), text: state.newContent }
      ],
      newContent: ""
    }));
  };
  addNewContent = content => {
    this.setState({ newContent: content });
  };

  render() {
    return (
      <React.Fragment>
        <ContentCreator
        value={this.state.newContent}
        handleChange={this.addNewContent}
        handleClick={this.submitNewContent}
        />
        {this.state.reversed ? <ReversedContentDisplayer contents={this.state.contents} /> : <ContentDisplayer contents={this.state.contents} />}
        <Reversifier reversed={this.state.reversed} handleReverse={this.handleReverse}/>
      </React.Fragment>
    );
  }
}

Как видите, контейнер имеет только состояние, некоторые методы для обновления состояния и дочерний компонент.Ни один html не используется внутри его метода рендеринга.

Наш первый дочерний компонент - ContentCreator

function ContentCreator({
  handleChange,
  handleClick,
  value
  }) {
  return (
    <div className="App">
      <label> New Content</label>
      <input type="text" value={value} onChange={event => handleChange(event.target.value)} />
      <button onClick={handleClick}>Add Content</button>
    </div>
  );
}

Этот компонент действует как форма (мне лень на самом деле оборачивать егос формой и функцией onSubmit).И основная цель этого компонента - обновить ключ contents нашего источника истинного состояния

Второй компонент называется Reversifier (хотя я не верю, что такое слово существует)

function Reversifier({reversed, handleReverse}) {
  return <button onClick={handleReverse}>{reversed ? 'Back to normal' : 'Reversify'}</button>
}

Основная цель этого компонента - переключить reversed ключ нашего источника истинного состояния.Вы также можете видеть, что в зависимости от значения reversed текст внутри кнопки также изменяется (по-разному отражает различные сценарии)

И наши последние два компонента

function ContentCreator({
  handleChange,
  handleClick,
  value
  }) {
  return (
    <div className="App">
      <label> New Content</label>
      <input type="text" value={value} onChange={event => handleChange(event.target.value)} />
      <button onClick={handleClick}>Add Content</button>
    </div>
  );
}

function ReversedContentDisplayer({ contents }) {
  return (
    <div className="App">
      {contents.map(content => (
        <div key={content.id}>{content.text.split("").reverse().join("")}</div>
      ))}
    </div>
  );
}

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

function ContentDisplayer({ contents, reversed }) {
  return (
    <div className="App">
      {contents.map(content => (
        <div key={content.id}>{reversed ? content.text.split("").reverse().join("") : content.text}</div>
      ))}
    </div>
  );
}

Но для отражения разных сценариев я создал два отдельных компонента

Я создал коды и поле для вас на случай, если вы захотитечтобы поиграть с функциональностью, смотрите конечный результат https://codesandbox.io/s/04rowq150

Таким образом, вам не нужно создавать какой-либо контент внутри Container, скорее вы можете использовать Container в качестве ориентираопределив начальное состояние и пару методов для передачи его потомков, чтобы они могли создавать новое содержимое, и отображая это вновь созданное содержимое от имени Container

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

0 голосов
/ 22 февраля 2019

Характер реакции - верх / низ.Поэтому, если вам нужно поделиться частью состояния или некоторыми данными для передачи в качестве реквизита, вам нужно поднять этот код до его родителя.Хорошо передавать Jsx в качестве реквизита, здесь вам нужно это сделать, и вы можете.

Дополнительная информация: состояние подъема

——————

A

/ \

B C

Так что если вы поделилиськод между B и C вы поднимаете это к A и передаете это B и C как подпорки.Если вам нужно состояние из B в C, вы поднимаете состояние до A. Если вам нужно получить доступ и изменить состояние из A в B или C, вы просто передаете функцию в качестве обратного вызова B или C

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