Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在父级中的状态更改后,强制在React上重新渲染D3组件_Javascript_Reactjs_Typescript_D3.js - Fatal编程技术网

Javascript 在父级中的状态更改后,强制在React上重新渲染D3组件

Javascript 在父级中的状态更改后,强制在React上重新渲染D3组件,javascript,reactjs,typescript,d3.js,Javascript,Reactjs,Typescript,D3.js,我有两个react组件(在typescript中)。在第一个组件中,我有一些菜单 <Menu.Item name="graph" active={activeItem === "graph"} onClick={this.handleItemClick} /> <Menu.Item name="flow" active={activeItem === "flow"} onClick={

我有两个react组件(在typescript中)。在第一个组件中,我有一些菜单

   <Menu.Item
      name="graph"
      active={activeItem === "graph"}
      onClick={this.handleItemClick}
    />
    <Menu.Item
      name="flow"
      active={activeItem === "flow"}
      onClick={this.handleItemClick}
    />
在render函数中,我将此决策作为属性传递给另一个react组件D3Core

回来之前,

var child = this.state.selection==="graph"? true : false ;
内部返回

<D3Core renderfull = {child} width={this.state.width} height={this.state.height} data={data} />
我面临的问题是,当我第一次加载文档时,它会显示图形,但如果我离开菜单并返回菜单,它只加载div而不是图形。我想我必须重新渲染图形,但是怎么做呢

我猜这是因为所有的组件都已经渲染,d3计算根本没有发生。我应该在渲染内部进行计算吗

我附上了几个截图。第一个屏幕截图显示首次加载页面时呈现的图形。第二个屏幕截图显示,当我离开graph菜单返回时,graph并不是只呈现div元素

编辑1:是我的d3代码吗


我认为问题在于当
renderfull
关闭并再次打开时,React会从文档中删除旧的
div
,并添加一个新的,并且您的D3实例仍然连接到旧的(已删除的)div。但是,D3Core组件实例始终保持装载状态,因此,您不会得到一个新的
组件didmount
回调

componentDidMount() {
    const { width, height, data } = this.props;
    const force = d3
      .forceSimulation()
      .nodes(data.nodes)
      .force('charge', d3.forceManyBody().strength(-120))
      .force('link', d3.forceLink(data.links).distance(50))
      .force('center', d3.forceCenter(width / 2, height / 2));

const svg = d3
      .select(this.ctrls.mountPoint)
      .append('svg')
      .attr('width', width)
      .attr('height', height);
    ...

最干净的解决方案是将D3内容移动到
D3Core
的子组件(例如,假设该子组件名为
D3Sub
),并且只有在
renderfull
为true时才具有
D3Core
render
方法返回
。然后,当
renderfull
被关闭并再次打开时,
D3Sub
实例将被销毁,并将创建一个新的
D3Sub
实例,新实例将得到一个
componentDidMount
回调。

您在
div
中还有SVG吗,当组件被隐藏时,您是否会破坏SVG?@rioV8否我不会破坏它。我在帖子中添加了我的代码。
var child=this.state.selection==“graph”
足够了,表达式是布尔表达式,这解决了问题。但是,正如您所说的“React从文档中删除旧div并添加新div”,componentDidMount回调不应该再次触发吗?给定的
D3Core
组件实例上的
componentDidMount
回调只在该实例完全初始化后调用一次。在此之后,实例可能会多次重新渲染(导致添加和/或删除DOM元素和子组件),每次您都会得到一个
componentDidUpdate
,而不是
componentDidMount
。原则上,您可以编写
componentdiddupdate
来检查
renderfull
是否从false变为true,如果是,则初始化另一个D3实例,但是使用子组件可以避免在
componentDidMount
componentdiddupdate
之间重复代码。是否会在componentDidMount之前调用component did update?组件的第一次呈现调用
componentDidMount
,而不是
componentdiddupdate
;看见如果您的问题是关于父组件的
componentdiddupdate
与父组件重新渲染时刚刚创建的子组件的
componentDidMount
的顺序,我相信子组件的
componentDidMount
是第一位的,但您可以试试看。
componentDidMount() {
    const { width, height, data } = this.props;
    const force = d3
      .forceSimulation()
      .nodes(data.nodes)
      .force('charge', d3.forceManyBody().strength(-120))
      .force('link', d3.forceLink(data.links).distance(50))
      .force('center', d3.forceCenter(width / 2, height / 2));

const svg = d3
      .select(this.ctrls.mountPoint)
      .append('svg')
      .attr('width', width)
      .attr('height', height);
    ...
componentDidMount() {
    const { width, height, data } = this.props;
    const force = d3
      .forceSimulation()
      .nodes(data.nodes)
      .force('charge', d3.forceManyBody().strength(-120))
      .force('link', d3.forceLink(data.links).distance(50))
      .force('center', d3.forceCenter(width / 2, height / 2));

const svg = d3
      .select(this.ctrls.mountPoint)
      .append('svg')
      .attr('width', width)
      .attr('height', height);
    ...