5

i'm trying to create a list of documents dynamically with semantic-ui-react. I'd like to get the document title back when the list item is clicked. According to the documentation: https://react.semantic-ui.com/elements/list

there is an onItemClick prop for this reason, however when im using it i get a warning when it's rendered:

Warning: Failed prop type: Prop onItemClick in List conflicts with props: children. They cannot be defined together, choose one or the other.

Also clicking on the list item does nothing (atm i just want to log the doc title to the console). Here is the code:

handleListItemClick(event, data) {
  console.log("list item clicked: " + data.value);
}


buildResultsContainer() {
    return this.props.listOfResults.map((document,index) =>
      {
        return (
            <List.Item
              as='a'
              key={index}>
                <Icon name='file' />
                <List.Content>
                  <List.Header>{document.properties.title}</List.Header>
                  <List.Description>
                    {document.properties.description}
                  </List.Description>
                </List.Content>
            </List.Item>
      );
      }
    );
  }

  render() {
    return (
      <div>
        <List onItemClick={this.handleListItemClick}>
          {this.buildResultsContainer()}
        </List>
      </div>
    )
  }

Can you please tell me how to use properly the onItemClick prop for the List component?

Less important, do you have any tip how to refactor the list rendering? Just wanted to keep the render function short and clean, but this function call looks a bit overkill....

Thanks a lot!

1 Answer 1

5

I think maybe the intent when using onItemClick is that you would use the items prop on List since then you wouldn't have any children e.g.

render() {
    const items = this.props.listOfResults.map(document => {
      return {
        icon: 'file',
        content: document.properties.title,
        description: document.properties.description,
        onClick: e => console.log(document.title)
      }
    });

    return <List items={items} />
  }

If you had your listOfResults prop in the above format, you wouldn't even need to do this map and your render function would be super tight:

render() {
  return <List items={this.props.listOfResults} />;
}

Alternately, List.Item takes an onClick prop that you could define in your buildResultsContainer() function. Because each onClick function is unique based on the current document object, you will need to use an anonymous function to call your handleClick function as follows:

<List.Item
  onClick={() => this.handleClick(document.title)}
  ...etc
/>

You would then have:

handleClick = docTitle => {
  console.log(docTitle);
};

If what you wanted was obtainable from event.target, you could just pass the reference of handleClick to the onClick i.e.

handleClick = event => {
    console.log(e.target.innerText);
};

<List.Item
  onClick={this.handleClick}
/>
Sign up to request clarification or add additional context in comments.

9 Comments

Thanks! I tried so far the alternate idea: if i give an onClick for the List.item , the function is called immediately when the list is rendered. Which is kinda strange.
<List.Item onClick={e => console.log(document.title)} /> ?
In this case it works well. Strange (at least to my current reactjs knowledge) why onClick={this.handleListItemClick(document.properties.title)} gives different result.
because what you are passing there is function invocation, as opposed to reference to the function. I will add an example
Makes complete sense, it explains also why it was called during rendering in my attempt. Both of your suggestions worked flawlessly, thanks a lot!
|

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.