首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在不共享父级的反应组件之间进行通信?

如何在不共享父级的反应组件之间进行通信?
EN

Stack Overflow用户
提问于 2021-06-24 23:41:36
回答 2查看 225关注 0票数 0

我正在添加对已经存在的前端的响应,并且不确定如何在组件之间进行数据通信。

我有一个基本的文本输入组件和Span组件,分别挂载。当用户键入输入时,我希望span的文本更改为输入内容。

在此之前,我将从零开始启动一个反应性项目,因此输入和Span共享应用程序组件作为父组件。我会使用一个螺旋桨函数将文本状态从输入提升到App,并将值向下传递给Span作为支柱。但从无到有不是一种选择。

我考虑过:

  1. Redux等。由于我在这个项目中一个接一个地介绍React,而且一些团队成员没有反应经验,我想避免在非常必要之前使用Redux或其他状态管理库,对于这个简单的案例来说,这似乎太过分了。
  2. 响应上下文API。这似乎也不正确,因为我的理解是,对于在许多组件上共享的“当前经过身份验证的用户、主题或首选语言”之类的全局数据,应该保留上下文API,而不仅仅是为了在两个组件之间共享状态。
  3. UseEffect钩子。使用此钩子设置Span组件的内部HTML,即
代码语言:javascript
运行
复制
function Input() {
    const inputProps = useInput("");
    useEffect(() => {
        document.getElementsByClassName('page-title')[0].innerHTML = inputProps.value;

    })
    return (
        <div>
            <h3>Name this page</h3>
            <input 
                placeholder="Type here"
                {...inputProps} 
            />
        </div>
    );
}

哪种方式否定了使用的全部意义?

我现在已经使用了UseEffect钩子,但是在React文档或其他在线的地方还没有找到任何明确的答案,所以任何建议都是有帮助的。

谢谢。

Input.jsx

代码语言:javascript
运行
复制
import React, { useState, useEffect } from 'react';

function useInput(defaultValue) {
    const [value, setValue] = useState(defaultValue);

    function onChange(e) {
        setValue(e.target.value);
    }

    return {
        value, 
        onChange
    }
}


function Input() {
    const inputProps = useInput("");
    useEffect(() => {
        document.getElementsByClassName('page-title')[0].innerHTML = inputProps.value;

    })
    return (
        <div>
            <h3>React asks what shall we name this product?</h3>
            <input 
                placeholder="Type here"
                {...inputProps} 
            />
        </div>
    );
}


export default Input;

PageTitle.jsx

代码语言:javascript
运行
复制
import React from 'react';


function PageTitle(props) {
    var title = "Welcome!"
    return (    
        <span>{props.title}</span>
    )
}

;
export default PageTitle

Index.js

代码语言:javascript
运行
复制
// Imports

const Main = () => (
    <Input />
);

ReactDOM.render(
    <Main />,
    document.getElementById('react-app')
);

ReactDOM.render(
    <PageTitle title="Welcome"/>,
    document.getElementsByClassName('page-title')[0]
);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-25 15:50:35

在React中,数据应该将只有一个方向从父组件流到子组件。没有进入上下文/redux,这意味着将公共状态保持在需要公共状态的组件的共同祖先中并通过道具传递它。

作为一种特殊的解决方案,useEffect()的想法并不可怕,但我不会让PageTitle成为一个react组件,因为必须从另一个组件中设置值确实破坏了react模型。

我使用了useEffect()来设置没有响应的元素,比如文档标题和主体类,如下代码所示:

代码语言:javascript
运行
复制
const siteVersion = /*value from somewhere else*/;
//...

useEffect(() => {

    //put a class on body that identifies the site version
    const $ = window.jQuery;
    if(siteVersion && !$('body').hasClass(`site-version-${siteVersion}`)) {
        $('body').addClass(`site-version-${siteVersion}`);
    }

    document.title = `Current Site: ${siteVersion}`;
    
}, [siteVersion]);

在您的情况下,您可以以类似的方式对待span,将其视为反应范围之外的东西。

请注意,useEffect()的第二个参数是依赖项列表,因此useEffect()只在一个或多个更改时运行。

另一个问题是,您需要防范XSS (跨站点脚本)在代码中的攻击,如:

代码语言:javascript
运行
复制
//setting innerHTML to an unencoded user value is dangerous
document.getElementsByClassName('page-title')[0].innerHTML = inputProps.value;

编辑:

如果您想变得更整洁和更有反应-y,您可以将一个函数传递给设置PageTitle的输入组件:

代码语言:javascript
运行
复制
const setPageTitle = (newTitle) => {
    //TODO: fix XSS problem
    document.getElementsByClassName('page-title')[0].innerHTML = newTitle;
};

ReactDOM.render(
    <Main setPageTitle={setPageTitle} />,
    document.getElementById('react-app')
);

//inside Main:
function Input({setPageTitle}) {
    const inputProps = useInput("");
    useEffect(() => {
        setPageTitle(inputProps.value);
    })
    return (
        <div>
            <h3>React asks what shall we name this product?</h3>
            <input 
                placeholder="Type here"
                {...inputProps} 
            />
        </div>
    );
}
票数 0
EN

Stack Overflow用户

发布于 2021-06-25 13:54:10

您可以创建一个临时的或使用useContext钩子代替。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68123818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档