当我开始编码时,我主要试图赶上语法,但当我的项目增长时,我需要考虑设计和数据流。开始编写一些不再起作用的代码。
为了让这个问题更具体,我们来讨论一下 React 组件如何在它们之间传递数据。让我们玩得开心,把我们的 React 应用想象成一群来自《十一罗汉》的经验丰富的小偷(我希望你已经足够大了,还记得年轻的布拉德·皮特和乔治·克隆尼主演的这部电影)。主角丹尼·奥森 (Danny Ocean) 是一位刚刚被假释的小偷,他组建了一支由 11 名熟练罪犯组成的团队来完成一场精心策划的抢劫。他们的目标是:同时抢劫拉斯维加斯最受保护的三家赌场——贝拉吉奥 (Bellagio)、幻影 (Mirage) 和米高梅大赌场 (MGMGrand)——这三家赌场均归无情的特里·本尼迪克特 (Terry Benedict) 所有。团队面临曲折、千钧一发和巧妙的策略,以完成电影史上最大胆的抢劫之一。所以,让我们想象一下 React 组件是需要秘密通信的罪犯。
PS:我没有时间再看这部电影,所以我编了一些例子,而不是试图在情节中寻找完全匹配。
PS2:好的。我看完了一半的电影,因为它太好了。
我们开始吧
在 React 中,回调是组件之间共享数据的常见方法,特别是从子组件到父组件。这种模式允许数据在组件层次结构中向上流动。
于是,拉斯蒂(布拉德·皮特饰)前往寻找退休骗子索尔·布鲁姆,并递给他一张纸条,邀请他参与抢劫。索尔收到纸条后决定前往。
// Danny (Parent Component) const SaulBloom = () => { const [secretMessage, setSecretMessage] = useState(""); // Callback to handle the message from Rusty const handleRustyMessage = (message) => { setSecretMessage(message); }; return ( <div> <h1>SaulBloom Secret Message: {secretMessage}</h1> <Rusty sendToDanny={handleRustyMessage} /> </div> ); };
// Rusty (Child Component) const Rusty = ({ sendToDanny }) => { const sendSignal = () => { sendToSaul("All clear, move to the vault!"); // Sending secret signal }; return ( <div> <h2>Rusty: Sending Signal</h2> <button onClick={sendSignal}>Send Secret Message</button> </div> ); };
但是,如果需要所有船员都提供信息怎么办?假设抢劫策略的计划是共享状态。父组件(如 Danny Ocean)管理计划;所有船员都需要访问此信息。也许他们正在使用一些假释的谷歌文档,丹尼在其中发布了计划,并且成员阅读或更新了它。
在 React 中,状态用于在组件内部和组件之间共享和管理数据。当状态提升到公共父组件时,它可以充当其子组件的单一事实来源,从而实现轻松的数据共享。
// Danny (Parent Component) const SaulBloom = () => { const [secretMessage, setSecretMessage] = useState(""); // Callback to handle the message from Rusty const handleRustyMessage = (message) => { setSecretMessage(message); }; return ( <div> <h1>SaulBloom Secret Message: {secretMessage}</h1> <Rusty sendToDanny={handleRustyMessage} /> </div> ); };
// Rusty (Child Component) const Rusty = ({ sendToDanny }) => { const sendSignal = () => { sendToSaul("All clear, move to the vault!"); // Sending secret signal }; return ( <div> <h2>Rusty: Sending Signal</h2> <button onClick={sendSignal}>Send Secret Message</button> </div> ); };
计划已经准备好了,十一罗汉需要去赌场检查一下。然而,在大楼内发送纸质票据速度太慢,并且使用笔记本电脑也不方便。因此他们需要提前决定某些迹象。例如,弗兰克·卡托(Frank Catto)将在计划中扮演一个名誉扫地的荷官,他看到索尔如何进来,就知道抢劫开始了。
此示例说明了 React 中的自定义事件。在这里,它们不像普通 JavaScript 那样是内置的。但是,您仍然可以使用 EventEmitter 类等工具或 PubSub 或 EventTarget 等第三方库来实现自定义事件驱动架构。在现实生活中,我们使用这种模式,并且需要连接的组件并不靠近,因此 props 钻孔没有意义。例如,如果我们需要在模块关闭后显示促销横幅。
这是海洋隐喻的代码。
function CrewMeeting() { const [plan, setPlan] = useState('Rob Bellagio at 11 PM'); const updatePlan = () => { setPlan('Rob Bellagio and MGM Grand at 10 PM'); }; return ( <div> <h1>? Ocean's Eleven Heist Plan</h1> <p>Current Plan: {plan}</p> <button onClick={updatePlan}>Update Plan</button> <div> <CrewMember name="Danny Ocean" plan={plan} /> <CrewMember name="Rusty Ryan" plan={plan} /> <CrewMember name="Linus Caldwell" plan={plan} /> </div> </div> ); }
function CrewMember({ name, plan }) { return ( <div > <h3>? {name}</h3> <p>? Plan: {plan}</p> </div> ); }
在之前的设置中,团队成员至少可以看到彼此,但如果他们位于不同的地方,无法直接沟通怎么办?唯一的保护者是 Broadcast Channel API。
Broadcast Channel API 是一种浏览器本机解决方案,用于在浏览器选项卡、窗口或 iframe 之间共享来自确切来源的数据。它充当通信通道,向所有连接的上下文广播消息。
巴舍尔·塔尔 (Basher Tarr) 是剧组的爆破专家和黑客,在电影中最关键的时刻,他使用 EMP 装置(电磁脉冲)关闭了赌场的电源。然后每个人都知道是时候闯入金库了。
// create eventBus.js const eventBus = new EventTarget(); //event emitter component function SaulBloom() { const sendArrivalSignal = () => { console.log('?️ Saul Bloom: Enters the casino as the wealthy foreigner.'); // Emit the custom event 'heistStart' eventBus.dispatchEvent(new CustomEvent('heistStart', { detail: 'Saul has arrived' })); }; return ( <div > <h2>?️ Saul Bloom</h2> <button onClick={sendArrivalSignal}>Enter Casino</button> </div> ); }
// LivingstonDell.js 函数利文斯顿戴尔() { const sendSignal = (主题, 消息) => { eventBus.publish(主题,消息); }; 返回 ( <div> <p>我很高兴收到大学的任何建议和更正,因为我很确定有很多方法可以改进这篇文章。 <br> 我还想创建本文的第二部分,解释使用 iframe、通过后端 websocket 集成、通过后端长轮询集成、通过存储集成(例如索引数据库)的连接)、通过 URL 集成、通过第三个 dom 元素集成。但一定会的。</p> <p>感谢您的阅读</p> </div>
以上是从抢劫策略到反应状态:数据如何在组件之间流动的详细内容。更多信息请关注PHP中文网其他相关文章!