Есть несколько способов решить эту проблему.
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>
);
}
Но чтобы отразить разные сценарии, я создал два отдельных компонента.
Я создал для вас codeandbox на случай, если вы захотите поиграть с функциональностью, чтобы увидеть конечный результат https://codesandbox.io/s/04rowq150
Таким образом, вам не нужно создавать какой-либо контент внутри Container
, скорее вы можете использовать Container
в качестве ориентира, определив начальное состояние и пару методов для передачи его дочерних элементов, чтобы они могли создавать новое содержимое и отображать их. вновь созданное содержимое от имени Container
Я надеюсь, что этот образец поможет вам в качестве отправной точки, и я надеюсь, что я правильно понимаю ваше требование как минимум на 51%. Если у вас есть дополнительные вопросы или затруднения, дайте мне знать
person
Cagri Yardimci
schedule
22.02.2019