当前位置: 首页 > 知识库问答 >
问题:

更改道具值外部反应和重新加载组件

丌官哲彦
2023-03-14

正如标题所说,我想改变道具的值,并在外部js文件中重新加载组件。

<div data-group=""></div>
//external.js
const popupChat = document.getElementById('popupChatComponent');
popupChat.setAttribute('data-group', groupId);
//component.ts
export default class PopupChatRoot extends React.Component {
    private readonly groupId: string;

    constructor(props) {
        super(props);
        this.groupId = this.props.group;
    }

    render() {
        return (
            <div className="modal-body">
                <p>{this.groupId}</p>
            </div>
        );
    }
}

const component = document.getElementById('popupChatComponent');
if (component) {
    const props = Object.assign({}, component!.dataset);
    render(<PopupChatRoot {...props}/>, component);
}

我怎么能做到这一点?

共有2个答案

高寒
2023-03-14

这只是一个普通的例子,它可能会帮助你解决你的问题。事实上,我不认为你可以改变根节点的道具。

// yourEventService.js
class YourEventService {

  listeners = []

  subscribe = listener => this.listeners.push(listener)

  unsubscribe = listener => this.listeners = this.listeners.filter(item => item !== listener)

  emit = message => listener.forEach(listener => listener(message))

}

export default new YourEventService() // singleton export
// someWhereElse.js

import yourEventService from './yourEventService'

window.addEventListener('click', () => yourEventService.emit('myNewGroup')) // it's just an event example

//component.js, sorry I don't know how to typescript well
import yourEventService from './yourEventService'

export default class PopupChatRoot extends React.Component {

    state = {
        groupId: this.props.group; // initial value is passed by props
    }


    componentDidMount() {
        yourEventService.subscribe(this.handleMessage)
    }

    componentWillUnmount() {
        yourEventService.unsubscribe(this.handleMessage)
    }

    handleMessage = message => {
        this.setState({ groupId: message })
    }

    render() {
        return (
            <div className="modal-body">
                <p>{this.state.groupId}</p>
            </div>
        );
    }
}

const component = document.getElementById('popupChatComponent');
if (component) {
    const props = Object.assign({}, component.dataset);
    render(<PopupChatRoot {...props}/>, component);
}
吴举
2023-03-14

您可以使用包装器组件或更高阶的组件为您的组件提供这些道具,并将包装器组件与外部javascript代码集成。

下面是我用来做类似事情的一个HOC:

export interface MyHocProps {
    //the props you want to provide to your component
    myProp: any;
}

export const withMyHOC = <T extends any>(params: any) =>

<P extends MyHocProps>(WrappedComponent: React.ComponentType<P>): React.ComponentClass<defs.Omit<P, keyof MyHocProps>> => {

    return class extends React.PureComponent<defs.Omit<P, keyof MyHocProps>> {

        //here you have access to params, which can contain anything you want
        // maybe you can provide some sort of observable which causes this to re-render

        render() {

            return <WrappedComponent
                {...this.props}
                myProp={/*whatever*/}
            />;
        }
    }
};

从这里开始,您可以将这个HOC与某种系统集成,以推动对其进行更改。我建议使用可观察的。基本上,您希望让这个HOC组件订阅某些可观察数据中的更改,然后在更改时强制自己重新渲染。

或者,如果组件只是一个单例,您可以通过执行类似于window的操作来公开组件上的某些方法。reloadThisComponent=this。重新加载捆绑(这个) ,但这可能是最后的选择。

 类似资料:
  • 我知道这不是react router的默认行为/功能,可以帮助我们轻松地重新加载当前组件,但我真的需要在我的应用程序中使用它。 我的应用程序处理产品。我有一个可以加载的产品列表,当我单击某个项目时,它会显示相关的产品详细信息。 在该页面上,我有加载相同组件的相关产品链接,但有另一个产品详细信息,位于 我在我的组件willmount中获取数据,似乎如果我只更改URL,就不会装载新组件,因此,我总是显

  • 问题内容: 我正在尝试将表示性组件与容器组件分开。我有一个和一个。容器负责触发redux操作,以根据当前用户获取适当的网站。 问题是在最初呈现容器组件之后,异步获取了当前用户。这意味着容器组件不知道它需要重新执行其函数中的代码,该代码将更新数据以发送到。我认为我需要在其props(user)之一更改时重新渲染容器组件。如何正确执行此操作? 问题答案: 您必须在方法中添加条件。 该示例用于比较对象。

  • 我试图将表示组件与容器组件分开。我有一个和一个。容器负责触发redux操作,以基于当前用户获取适当的站点。 问题在于,在容器组件最初呈现之后,当前用户是异步获取的。这意味着容器组件不知道需要在其函数中重新执行代码,该函数将更新数据以发送到。我想当容器组件的一个道具(用户)发生变化时,我需要重新渲染它。如何正确地执行此操作?

  • 悬而未决...

  • 问题内容: 默认情况下,使用内置服务器()运行Flask应用程序时,它会监视其Python文件并在代码更改时自动重新加载该应用程序: 不幸的是,这似乎仅适用于* .py文件,而且我似乎没有找到任何将此功能扩展到其他文件的方法。最值得注意的是,当模板更改时,让Flask重新启动应用程序将非常有用。我已经迷失了多少次我不喜欢模板中的标记,却因为看不到任何更改而感到困惑,只是发现该应用程序仍在使用旧版本

  • 这是父组件: 这是子组件: prop不会打印为子组件中的内容。 可能是什么问题?,已经在这个问题上很久了