在相邻组件之间共享内容,HOC?
Posted
技术标签:
【中文标题】在相邻组件之间共享内容,HOC?【英文标题】:Sharing content between adjacent components, HOC? 【发布时间】:2019-07-16 17:50:48 【问题描述】:我有一个容器组件,它在其中呈现两个组件。根据容器中的某些道具,顶部组件可以更改,但底部组件将始终保持不变。
我想渲染一些额外的内容(DOM 元素/其他反应组件)内部较低的组件,但额外的内容是在顶部组件内创建的。我正在努力弄清楚我需要在这里重构什么才能完成这项工作。我最初尝试将创建的内容传递给容器,然后返回到较低的组件。我很快意识到这不起作用,因为创建的内容依赖于创建它的组件的道具/状态。
在容器内创建内容是不可行的,因为可以创建的内容有很多不同的选项。我正在处理的代码库有 30-40 个可能的组件,它们都生成不同的内容。
我对 React 还很陌生,所以我很难尝试用 react 方式解决这个问题。我已经简要了解了渲染道具/HOC,也许这就是我需要的?任何帮助将不胜感激。
这是一个非常基本的示例:https://codesandbox.io/s/zqo2p1yy9m
【问题讨论】:
您可以提升状态和/或创建 jsx 并将其作为道具传递。你不需要 hocs 也不需要 renderprops 是的,就像@victor.ja 提到的那样,您需要提升组件的状态。他指给你的文章是你能得到的最好的解释:reactjs.org/docs/lifting-state-up.html阅读后回访,如果你仍然不确定如何解决这个问题,我们可以举个例子。 【参考方案1】:有几种方法可以解决这个问题
1) 可以使用 Redux、mobx 等状态管理系统,也可以使用 React 的 context API https://reactjs.org/docs/context.html。但是,由于您对 React 还很陌生,我建议您在熟悉基本流程之前不要处理这些正确的知识
2) 你可以实现一个简单的parent-child relationship
在组件之间传递数据。最终,这允许您在相邻(兄弟)组件之间提供通信。正如已经说过的,这种流动通常被称为提升状态。实际上,状态管理系统以类似的方式工作。让我通过考虑基于场景的代码示例来解释这个逻辑。
我们将拥有一个 Container 组件。该组件将是一个有状态的组件。这个 Container 组件的唯一目的是拥有自己的整体状态,这将被其子组件视为事实的来源。有几种方法来定义更新这种整体状态的方法。子组件将是纯组件或代表性组件。这意味着,他们不会有自己的状态。它们要么用于显示其父级传递给它们的数据,要么用于触发其父级定义的方法以更新真实状态源。
我们将有两种情况: 在场景 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% 正确。如果您还有其他问题或困惑,请告诉我
【讨论】:
【参考方案2】:react 的本质是自上而下。因此,如果您需要共享一部分状态或一些数据以作为道具传递,您需要将该代码提升到其父级。 把 Jsx 作为 props 传递就可以了,这里你需要这样做,你可以。
更多信息:lifting state
——————
一个
/\
B C
因此,如果您在 B 和 C 之间共享代码,则将其提升到 A 并将其作为道具传递给 B 和 C。 如果在 C 处需要 B 的状态,则将状态提升到 A。 如果需要在 B 或 C 访问和修改 A 的状态,只需将函数作为回调传递给 B 或 C
【讨论】:
【参考方案3】:我同意 victor.ja,但我想知道您是否有像 redux 这样的全球商店。然后,您只需调用该操作即可从顶部组件更新商店的状态。高阶组件可以接收 store 的状态作为 prop 并更新低阶组件。
【讨论】:
以上是关于在相邻组件之间共享内容,HOC?的主要内容,如果未能解决你的问题,请参考以下文章