简体   繁体   中英

ReactJS onClick in list item

I have a list and I wanna set onClick event when a list item is clicked. But my function isn't triggered even though I have bind the function.

I have looked at TODO example ( TODO GITHUB ). In that example, onClick list item will dispatch an action and in the end it will change the Global State (Redux Store).

What I wanna have is, when I click list item, it won't change Global State but it just change local state. I have initialize local state and onClickItemHandler function, but it seems my function isn't executed (no console.log result in chrome console).

Here is my code

// Searchable Component
class Searchable extends Component{
  constructor(props,context){
    super(props);
    this.state ={
      listAccount: [],
      style:{
        searchResultList:{
          listStyle: 'none',
          width: '100%',
          height: '0em'
        },
        searchResultItem:{
          listStyle: 'none',
          width: '100%',
          height: '0em'
        },
      }
    };

    this.onChange = this.onChange.bind(this);
    this.onFocus = this.onFocus.bind(this);
    this.onBlur = this.onBlur.bind(this);
    this.onItemClickHandler = this.onItemClickHandler.bind(this);
  }

  onChange(event){
    this.props.onInputChange(this.props.data.type, this.props.data.id,event.target.value);
  }

  onFocus(event){
    console.log("input on focus");
    const showResultList= {
      height: '10em',
      overflow:'auto'
    };

    const showResultItem= {
      height: '2.4em',
      visibility: 'visible'
    };

    let style= this.state.style;
    style.searchResultList = showResultList;
    style.searchResultItem = showResultItem;
    this.setState({style});
  }

  onBlur(event){
    console.log("input on Blur");
    const showResultList= {
      height: '0',
      overflow:'hidden'
    };

    const showResultItem= {
      height: '0',
      visibility: 'collapse'
    };

    let style= this.state.style;
    style.searchResultList = showResultList;
    style.searchResultItem = showResultItem;
    this.setState({style});
  }

  onItemClickHandler(event){
    console.log("test");
    console.log(event.target);
  }

  render(){
    return(
      <div className="searchable">
        <input type="search" className="input-searchable" value={this.props.data.input} onChange={this.onChange} onFocus={this.onFocus} onBlur={this.onBlur}/>
        <div className="search-result">
          <SearchResultList
            ResultList={this.props.accounts}
            listStyle={this.state.style.searchResultList}
            listItemStyle={this.state.style.searchResultItem}
            onClick={this.onItemClickHandler}
          />
        </div>
      </div>
    );
  }
}

// SearchResultList Component
const SearchResultList = ({ResultList, listStyle, listItemStyle, onClick}) => (
  <ul style={listStyle} onClick={onClick}>
  {
    ResultList.map((item,idx) =>
      <SearchResultItem
        key={++idx}
        style={listItemStyle}
        text={item.name}
        onClick={onClick}
        />
    )
  }
  </ul>
);


// SearchResultItem Component
const SearchResultItem = ({ onClick, text, style}) => (
  <li
    style={style}
    onClick={onClick}
    >
    {text}
  </li>
);

you need to bind your onClick function:

try

    <SearchResultList
      ResultList={this.props.accounts}
      listStyle={this.state.style.searchResultList}
      listItemStyle={this.state.style.searchResultItem}
      onClick={::this.onItemClickHandler}
    />

or

    <SearchResultList
      ResultList={this.props.accounts}
      listStyle={this.state.style.searchResultList}
      listItemStyle={this.state.style.searchResultItem}
      onClick={this.onItemClickHandler.bind(this)}
    />

They do the same thing, binding this to your function. I believe it is getting executed upon render because it isn't being bound correctly.

Also, in case you are passing these methods to multiple children and are worried about performance, you can bind in the constructor like so:

constructor(props) {
    super(props)
    this.onItemClickHandler = this.onItemClickHandler.bind(this)
}

then use

   <SearchResultList
      ResultList={this.props.accounts}
      listStyle={this.state.style.searchResultList}
      listItemStyle={this.state.style.searchResultItem}
      onClick={this.onItemClickHandler}
    />

If you are worried about performance you can use es7 class property. You wont need to manually bind your function in the constructor this way. So DRY yay!!

    onItemClickHandler = (event) => {
        console.log("test");
        console.log(event.target);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM