简体   繁体   English

在React中将实例变量从一个子组件传递到另一个子组件

[英]Passing instance variables from one child component to another in React

I have some trouble understanding how to pass component instance variables in React ( live example ). 我在理解如何在React实时示例 )中传递组件实例变量时遇到一些麻烦。 My hierarchy is as follows: 我的层次结构如下:

DataView
 |> SharedScale
 |> Graph1
 |> Graph2
 |> ...

The idea is to create a shared, D3 axis/scale in SharedScale and pass it to all other graphs via the DataView wrapper (ie a reference scale is supposed to be shown at the top of the page). 这个想法是在SharedScale创建一个共享的D3轴/比例 ,并通过DataView包装器将其传递给所有其他图形(即,应该在页面顶部显示参考比例)。 The scale implementation can change, when the component is resized for example (ie it's created in the render function in my case): 例如,当调整组件的大小时(例如,在我的情况下,它是在render函数中创建的),缩放实现可以更改:

class SharedScale extends React.Component {    
  render() {  
    // Create a D3 scale; i.e. an external library object, which is not serializable
    this.scaleImpl = ...

    // Render a D3 axis using the scale implementation
    return <div>{this.scaleImpl}</div>; 
  }
};

The Graph is supposed to get a reference to SharedScale , and render a D3 chart , based on it: Graph应该获得对SharedScale的引用,并基于它渲染D3图表

class Graph extends React.Component {
   render() {    
     //Use the scaleImpl here to render the graph body
     return (
       <div>{get(this.props, "scaleComponent.scaleImpl", "no scale implementation")}</div>
     );
   }
}

I'm trying to combine this together in the DataView , using React.createRef as such: 我正在尝试使用React.createRef这样在DataView中将其组合在一起:

class DataView extends React.Component {   
    constructor(props) {
      super(props);

      this.scaleComponent = React.createRef();
    }

    render() {
        return(
          <div>
            <SharedScale ref={this.scaleComponent} />
            <Graph scaleComponent={this.scaleComponent.current} />                
          </div>
        );
     }
}

The problem is that the render() function is only called once. 问题在于render()函数仅被调用一次。 That is, the current field is consistently null . 也就是说, current字段始终为null

Am I missing something, or is this approach fundamentally flawed for some reason? 我是否缺少某些东西,还是这种方法由于某种原因而存在根本性的缺陷?

As it turns out, one can trigger an additional render event by calling forceUpdate in componentDidMount : 事实证明,可以通过在componentDidMount调用forceUpdate来触发其他render事件:

class DataView extends React.Component {   
  ...

  componentDidMount() {
    this.forceUpdate();
  }
}

From componentDidMount reference page: componentDidMount参考页面:

You may call setState() immediately in componentDidMount(). 您可以立即在componentDidMount()中调用setState()。 It will trigger an extra rendering, but it will happen before the browser updates the screen. 它会触发额外的渲染,但是会在浏览器更新屏幕之前发生。 This guarantees that even though the render() will be called twice in this case, the user won't see the intermediate state. 这样可以保证即使在这种情况下render()将被调用两次,用户也不会看到中间状态。 Use this pattern with caution because it often causes performance issues. 请谨慎使用此模式,因为它经常会导致性能问题。 In most cases, you should be able to assign the initial state in the constructor() instead. 在大多数情况下,您应该可以改为在Constructor()中分配初始状态。 It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position. 但是,在模态和工具提示之类的情况下,当您需要在渲染取决于其大小或位置的对象之前测量DOM节点时,可能是必需的。

This is more or less equivalent to calling forceUpdate . 这或多或少等效于调用forceUpdate

Updated live example can be found here . 更新的实时示例可以在此处找到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM