jQuery-Like Way to Find / Select Array of React Elements

2.5k Views Asked by At

I created this little function to find children of a specific type.

I'd like to be able to select children via property like jQuery, [name="example"]. Is there any way to strip the string selector functionality from jQuery to create an object map to feed to something like lodash's _.find?

I realize this is a fake solution for selecting / finding / filtering an array but I think it can be really useful. I also know that it won't find deep children, it would just deal with direct root children.

Does this exist within react already?

function containsElement (element, children) {
  var result = []
  element = _.flatten([element])
  if (React.isValidElement(children) && !_.isArray(children)) {
    var contains = _.contains(element, children.type)
    if (contains) return children
    return false
  } else if (!React.isValidElement(children) && !_.isArray(children)) {
    return false
  }
  children.forEach(function (child) {
    var isElm = React.isValidElement(child)
    var contains = _.contains(element, child.type)
    if (isElm && contains) {
      result.push(child)
    }
  })
  if (!result.length) return false
  return result
}
2

There are 2 best solutions below

0
ThomasReggi On BEST ANSWER

Here's a simple version of what I want that only supports element type.

selectElements('div, span', this.props.children)

Ideally I can do this and it would get all divs with the name prop set to hello.

selectElements('div[name="hello"]', this.props.children)

Here's full example, (jsbin).

var selectElements = function (selectorString, reactElements) {
  var selectors = selectorString.split(',')
  selectors = _.map(selectors, function (item) {
    return item.replace(/^\s+|\s$/, '')
  })
  return _.filter(reactElements, function (reactElement) {
    return _.contains(selectors, reactElement.type)
  })
}

var OnlyElements = React.createClass({
  displayName: 'OnlyElements',
  getInitialState: function () {
    return {
      children: this.props.children
    }
  },
  componentWillMount: function () {
    this.setState({
      children: selectElements(this.props.allow, this.props.children)
    })
  },
  render: function () {
    return (
      <div>
        {this.state.children}
      </div>
    )
  }
})

var Test = React.createClass({
  displayName: 'Test',
  render: function () {
    return (
      <OnlyElements allow='div'>
        <span>Alpha</span>
        <div>Beta</div>
        <span>Gamma</span>
      </OnlyElements>
    )
  }
})

React.render(<Test/>, document.body)
2
François Zaninotto On

There is a little open-source library called react-query that does exactly that.

edit: The react-query repository has been archived by the owner. It is now read-only.