4

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
}
13
  • 2
    If you're using a modern browser, the majority of the selector power in jQuery is available natively using document.querySelectorAll which uses the css selector engine. You could also instead use sizzle, which is what jQuery's selector engine is built upon. Commented Sep 21, 2015 at 19:04
  • 1
    But I want to supply the HTML / elements as in this.props.children. Commented Sep 21, 2015 at 19:12
  • @KevinB +1 for mentioning Sizzle. ThomasReggi do check out Sizzle, it may well be the answer to your question. Commented Sep 21, 2015 at 19:15
  • Just tried this Sizzle.matches('tr', this.props.children) didn't work. Returning empty array. Could it be because it's not a real DOM element array? Commented Sep 21, 2015 at 19:21
  • 1
    Why would you need such a function when working with React? It's probably not helpful to use a "jquery" tag when asking a React question because the imperative DOM manipulation of jQuery doesn't mix well with React's declarative approach. A "how to do x?" question with just a "reactjs" tag might yield an enlightening answer. Commented Sep 21, 2015 at 20:06

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

It seems react-query is abandoned, this other lib should do the trick: teaspoon
@Zaninotto teaspoon has been archived by the owner. It is now read-only. would you share with us what do you use currently?
0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.