Semantic-UI-React: Search Component: Unknown props error

I have a search component with a custom renderer and I keep getting the error Warning: Unknown props _id, url, ... on <div> tag. Remove these props from the element..

The array I pass to results has these extra props, mentioned in the error, but I am using a custom renderer, so it seems to me they should be ignored.

Here is my custom renderer

const resultRenderer = ({ _id, name, url, logo}) => {
    return (
        <div key={_id}>
            <Label content={name}  />
        </div>
    )
}

resultRenderer.propTypes = {
  name: PropTypes.string
}

My component is really simple

export default class CompanyForm extends Component {
    constructor(props) {
        super(props);

        this.state = {
            isLoading: false,
            value: '',
            results: [],
            company: null
        };
    }

    handleResultSelect(e, result) {
        this.setState({
            value: result.name,
            company: result
        });
    }

    handleSearchChange(e, value) {
        this.setState({
            value: value
        });       
        client
            .service('/api/companies')
            .find({
                query: {
                    name: {'$search': value }
                }
            })
            .then(results => {
                this.setState({
                    isLoading: false,
                    results: results.data
                });
            })
            .catch(err => {
                console.error(err);
            })
        
    }

    render() {
        const {isLoading, value, results} = this.state;
                
        return (
            <Search
                loading={isLoading}
                onResultSelect={this.handleResultSelect.bind(this)}
                onSearchChange={ this.handleSearchChange.bind(this)}
                results={results}
                value={value}
                resultRenderer={resultRenderer}
            />
        );
    }
}

The above code is what’s causing the warning.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 7
  • Comments: 41 (7 by maintainers)

Most upvoted comments

All our components “consume” their own props and pass the extra props along (best practice).

This may be the best practice, but annoying in this instance as I assumed defining a custom renderer would allow me to decide what props are passed to the rendered element.

I’d also like to say that I agree with @koernchen02 and either would like to be able to define custom fields like he talks about or have the control over which props get used in the custom renderer.

I have to ask this again… You are saying the OP has to remove the extra keys from each result object before passing … results.data to the results prop. But how is it then possible to use the properties in the customRenderer for a single result? In the example code he wants to assign the id as the result-div’s key via <div key={_id}> how is this possible if the _id property has gotten removed from each single result? Is it at all possible, to use custom fields (other than “title”, “description”, “price” and “image”)?

This may be the best practice, but annoying in this instance as I assumed defining a custom renderer would allow me to decide what props are passed to the rendered element.

Whoa, looks like I misunderstood this one completely guys. Appreciate the extra effort to reach me. The user should definitely have full control over every prop used in all our components.

@jcarbo your eyes appreciated on this:

Looking at the code again, it looks like there is no way for the user to control the props of the <SearchResult /> as the resultRenderer does not render the SearchResult itself but only the children of the SearchResult. Whilst, we are spreading all the original SearchResult props on the actual SearchResult with no hook for the user.

My thinking is that the renderResult should require the user to return a Search.Result or its shorthand. In other words, we should be using a shorthand factory here, SearchResult.create(). This way, they are in full control of the props on the SearchResult itself, and not the children only. Otherwise, they have no way to filter the props that are applied to the SearchResult.

Thoughts?

(comment updated)

Hi I’ve just struggled myself, but there is a more or less simple solution to this problem. Code:

// Some extra fields
// childKey is important! Otherwise o.title is used by default for <SearchResult> key
// and may lead to errors 
const mapToSearchResult = map(o => ({
      childKey: o.id,                                              //!!!!!
      as: IngredientsSearchResultWrapper,         //!!!!!
      id: o.id,
      title: o.title,
      image: o.picUrl,
      shortDesc: o.shortDescription || '',
      fullDesc: o.fullDescription || ''
    }))
const IngredientsSearchResultWrapper = (params) => (
  <div className={params.className} onClick={e => params.onClick(e)}>
    {params.children}
  </div>
)

const IngredientsSearchResult = ({id, title, image, shortDesc, fullDesc}) => {
  const style = !!image ? {backgroundImage: `url(${ingredient_pic_search(image)})`} : {}

  return (
    <div key={id}>
      <div className="pic" style={style}></div>
      <div className="main">
        <div className="title">{title}</div>
        {!!shortDesc &&
          <div className="desc">{shortDesc}</div>
        }
      </div>
    </div>
  )
}

<Search
      resultRenderer={IngredientsSearchResult}
      onResultSelect = {onResultSelect}
      onSearchChange = {onSearchChange}
      results = {results}
      minCharacters = {0}
      fluid
      value = {value}
      open = {true}
    />

Based on tom-wagner comment and iamdanthedev’s suggest work around I am closing this.

Why consumer of this component being force to use object schema predefined by author/contributor of this component, which is like {title, price, etc...} at-lease result renderer should be given free hand to decide whatever props we want to use to render the result.

Any updates?

Search component in the current state is too opinionated. I think this could be an easy fix. Just allow pass throw for one custom prop. It should allow containing a custom object.

Additionally:

/** A unique identifier. */
id: PropTypes.number,

Em, why number? This should allow for string input to. For results from MongoDB where ID is a string. I return string id from Postgres to, as numeric ID could grow out of javascript number size.

Returning a SearchResult seems like a decent solution. As you said it would give anyone full control over what props are passed to it.

You need to parse it in your results renderer before it’s displayed

Unknown props like other meta data of my search show on html as attribute and it is because of unhandled props, so what if you handle the props like create prop of “metadata” or “data” where we pass other property to that prop so it will not show in the DOM and pass that prop when selecting result.

Example of passing other props (although, no errors being shown, it is kinda awkward to see these attributes on the DOM): <div hello="e" otherdata="321" class="active result"></div>

@martindale in this example it was from FeathersJS, but it could be any HTTP client though.