Существует несколько способов решения этой проблемы
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% правильно.Если у вас есть дополнительные вопросы или сомнения, пожалуйста, дайте мне знать