mardi 3 mai 2016

React JS manipulating children pattern

I am new to react and I would like to know the best pattern for cascading an action to child elements.

Specially, I am trying to build a tree like widget in React.js. Each branch of the tree is a React class called "CollapsableSection" which contains a '+' or '-' button to collapse or expand that branch. If the branch is expanded then the children are hidden, otherwise they are shown. The state is stored within each CollapsableSection in state.collapsed.

So far this works well, but now I am trying to create two top level buttons called "Expand All" or "Collapse All" which will expand or collapse all branches in the tree. I have considered some different methods of accomplishing this.

Method 1:

I could send a property to my CollapsableSection called forceCollapse which would be set equal to Date.now() upon clicking the "Collapse All" button. Then within the CollapsableSection I would also store the Date.now() in state.userInteractionTime and update it whenever the +/- button is directly clicked on. Then within the Render method of the CollapsableSection I would a collapse state based on whichever timestamp was larger. This was if the "Collapse All" button is clicked, all the children will collapse but the user would then be able to reclick on open selected branches.

Method 2:

I could somehow use component refs to store a reference to all children with the parent and then whenever the Expand All is clicked it would call the expand function of all the children.

As a further consideration, I might want to put these expandAll / collapseAll buttons at different levels of my tree where they would cascade to any branches below them. Here is an examples of what I'm looking for:

Initial Tree:
[++][--]
  [+]Section 1 
  [+]Section 2

After Clicking top level [++] (Expand All):
[++][--]
  [-]Section 1 
     [-]Subsection 1A
        content 1A 
     [-]Subsection 1B
        content 1B
  [-]Section 2
     [-]Subsection 2A
        content 2A part1
        [-]Subsubsection 2AA
           contents 2AA
        content 2A part2
     [-]Subsection 2B
        content 2B

Note that as I currently have it set up it is possible to combine leaves and branches as shown in Subsection 2A.

Here is the current code of my react component:

var CollapsableSection = React.createClass({
  getInitialState: function() {
    return {collapsed: JSON.parse(this.props.initialCollapse)};
  },
  handleClick: function(event) {
    this.setState({collapsed: !this.state.collapsed});
  },
  render: function() {
    var headerStyle = {fontSize: '2em', margin: '.67em 0'};
    if (this.props.headerStyle) {headerStyle = this.props.headerStyle;}

    //var text = this.state.liked ? 'like' : 'haven\'t liked';
    var thestyle={display: ((this.state.collapsed)?'none':'block')};
    var thetext=((this.state.collapsed)?'+':'-');
    return (
      <div>
        <div style={headerStyle}>
          <button onClick={this.handleClick} value={thetext}>{thetext}</button>
          {this.props.title}
        </div>
        <div style={thestyle}>
          {this.props.children}
        </div>
      </div>
    );
  }
});

Question:

What is the cleanest way to create the functionality I am looking for in React.js? I would prefer to use only react and vanilla javascript unless they is a very compelling reason to use something else.

Aucun commentaire:

Enregistrer un commentaire