首页 > 解决方案 > 以声明方式更新组件内的标记

问题描述

我的应用程序中有一个组件可以呈现一些数据,最常见的是页面标题。

标记

<Toolbar>
  <ToolbarRow>
    <div id="title-bar">
      {children}
    </div>
  </ToolbarRow>
</Toolbar>

我将如何以声明方式更改内部数据?

我已经尝试过react-side-effects,这让我确实可以更改要呈现的标题,但是我也希望能够添加组件。

组件不能存储在 state 中,所以……</p>

然后我查看了 Portals,这似乎正是我想要的,但我得到了Target container is not a DOM element.

门户组件的标记

import React from "react";
import {createPortal} from 'react-dom'

const PageTitle = ({title, children}) => {
  return createPortal(
    <p>foo</p>,
    document.getElementById('title-bar')
  )
};

export default PageTitle;

我这样调用门户组件:

<PageTitle title="Document Overview"/>

从上面的代码片段可以看出,另一个组件添加了一个<div id="title-bar" />,所以我猜它与时间有关。

有人有好主意吗?

标签: javascriptreactjs

解决方案


我只是将组件放入此处的状态:

  const bars = [];

  export class TitleBar extends Component {
    state = { children: [] };

    componentDidMount() { bars.push(this); }
    componentWillUnmount() { bars.splice(bars.indexOf(this), 1); }
    render() { return this.state.children };
 }

 const RealPageTitle = ({ title }) => <div> { title } </div>;

 export class PageTitle extends Component {
   constructor(props) {
     super(props);
     this.real = RealPageTitle(props);
   }

   componentDidMount() {
     for(const bar of bars)
       bar.setState(({ children }) => ({ children: children.concat(this.real) }));
   }

   componentWillUnmount() {
     for(const bar of bars)
      bar.setState(({ children }) => ({ children: children.filter(child => child !== this.real) }));
   }

   render() { }
 }

这样你就可以<PageTitle title={"Test"} />在页面上的某个地方添加它,它就会被添加到标题栏。

我知道这不遵循“最佳实践”,但它确实有效


推荐阅读