【问题标题】:React lifecyle methods, to componentWillReceiveProps or notReact 生命周期方法,是否对 componentWillReceiveProps
【发布时间】:2018-10-03 18:40:16
【问题描述】:

我正在使用 React 构建一个可折叠的 OrgChart 组件。

我不确定如何根据用户交互使用生命周期方法重新渲染边缘(链接 2 个节点的 SVG 路径)。我想知道在这种情况下是否有比使用componentWillReceiveProps 更好的方法(或者因为它很快就会过时,componentDidUpdate 和/或getDerivedStateFromProps

只有在首先绘制所有节点后才能绘制边缘。但是在我的代码中,每个Node 都会绘制其传入的边缘。这是因为使用CSS 使图表可折叠的HTML 代码需要Node 及其Edge 在同一div 下:

NodeContainer = (props) => 
  <div className='nodeContainer'>
    <Node />
    <Edge />
  </div>

我的OrgChart 组件有 3 个主要组件:

  • Chart.tsx:接收包含节点和边列表的graph 对象道具,并使用它来构建图表。还接收一些其他道具,例如用于图表或节点操作的回调函数(例如:onNodeSelected(id)onChartMoved()
  • Node.tsx:绘制节点及其传入的 svg 边缘。
  • Edge.tsx:绘制 SVG 边缘

到目前为止,我一直在考虑这样组织我的代码:

Chart.tsx

// augmentedGraph will have extra data for each node and edge.
// For example: the node coordinates, isCollapsed. The coordinates are purely a UI concern, hence why my incoming graph props should not contain the info.
class Chart extends Component {
  state = { augmentedGraph: this.props.graph }

  componentDidUpdate(prevProps, prevState) {

    if (this.props.graph.nodes.length !== prevProps.graph.nodes.length 
      || this.state.augmentedGraph !== prevState.augmentedGraph){

      // clone this.props.graph into this.state.augmentedGraph
      // and re-calculates all edges and nodes coordinates to add those properties to this.state.augmentedGraph
      ...

    }
  }

  // Will send callback function props to each Node (onNodeMoved, etc.), that will fire below method
  userModifiedChartHandler() {
    // re-calculates all edges and nodes coordinates and updates this.state.augmentedGraph
  }

  // recursively builds the chart html structure with Nodes and Edges.
  buildChart(node) {
    return ...
  }

  render() {
    const rootNode = this.state.augmentedGraph.nodes.root
    const chart = buildChart(rootNode)
    return ({chart})
  }
}

【问题讨论】:

  • 什么是buildChart
  • 使用生命周期方法而不是计算 render 方法中的所有内容,您的目标是什么?表现?如果是这样,你不能像 React 文档中描述的那样使用 memoization 吗?
  • @enguerran buildChart 是一个递归创建构建图表的 JSX 代码的函数。我没有在这里代表它,因为它与我的问题无关。
  • @DanielHilgarth 我的Chart 组件接收一个graph 道具,其中包含nodeedge 的数组,它们没有任何坐标数据。 graph 道具会触发重新渲染的唯一时间是用户更改其结构(删除、创建、移动节点)时。为了管理其他用户交互(例如折叠、移动图表、缩放等),我需要在Chart.tsxstate 中保留每个节点和边的坐标。因此,我需要使用 componentDidUpdate 生命周期方法来检查用户是否做了某事。因此,这不仅是为了性能,而且似乎只是为了让我的代码能够正常工作。

标签: javascript reactjs


【解决方案1】:

我会使用一个简单的memoization approach

calculateCoordinates = memoize((nodesLength, graph) => { your recalculation code })

render() {
    const augmentedGraph = this.augmentGraph(this.props.graph.nodes.length, this.props.graph);
    return {buildChart(rootNode, augmentedGraph)};
}

显然,您的问题中缺少很多细节。例如,我缺少augmentedGraphrootNode 之间的连接。
通常,记忆化方法用于从组件(在本例中为增强图)中删除状态。
传递给memoize 的 lambda 参数是您要确定输入数据是否已更改并且您需要重新执行计算代码的键。

【讨论】:

  • 谢谢丹尼尔。我添加了有关rootNode 的详细信息。我会看看我能用memoization 做什么,然后再回复你,因为我几乎是一个初学者,这对我来说需要时间。主要是,我想知道使Chart.tsx 有状态,augmentedGraph 基于具有额外节点和边缘坐标的this.props.graph,并使用componentDidUpdate 保持augmentedGraphthis.props.graph 同步是否有意义跨度>
  • 那么,图表上的用户交互——比如 onNodeMove——会改变augmentedGraph?也就是说,如果props.graph发生变化,那么对augmentedGraph所做的修改会丢失吗?
  • 是的:像 onMoveNode 这样的交互将会改变augmentedGraph。在我看来,来自服务器的this.props.graph 应该只关心创建、删除或更改节点父节点的用户交互。任何其他交互,例如 onNodeMove、onNodeCollapse 等都应该在 Chart.tsx 中处理。对augmentedGraph 所做的更改不应丢失。我会合并两者,因为augmentedGraph 是基本 = this.props.graph,但在里面,而不是 node: {id: 1, title: 'Node 1' },它将添加 node: {id: 1, title: 'Node 1', x: 145, y: 243}
  • 我会把这些分开。我会有一个以 id 为键的坐标散列图
  • 这又回到了记忆技术:augumentedGraph 总是可以从props.graphstate.coordinates 计算出来。
猜你喜欢
  • 2016-12-20
  • 2018-02-17
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
相关资源
最近更新 更多