2016-10-25 6 views
1

У меня есть список, и я хочу установить событие onClick при щелчке элемента списка. Но моя функция не срабатывает, хотя я связываю функцию.ReactJS onClick в элементе списка

Я рассмотрел пример TODO (TODO GITHUB). В этом примере элемент списка onClick отправит действие, и в конце он изменит глобальное состояние (хранилище Redux).

Что я хочу иметь, когда я нажимаю элемент списка, он не изменит глобальное состояние, а просто изменит локальное состояние. Я инициализирую локальное состояние и функцию onClickItemHandler, но, похоже, моя функция не выполняется (в консоли консоли не появляется консоль.log).

Вот мой код

// 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> 
); 

ответ

2

вам необходимо связать вашу функцию OnClick:

попробовать

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

или

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

Они делают то же самое, связывание это к вашей функции. Я считаю, что он выполняется на рендеринг, потому что он не связан правильно.

Кроме того, в случае, если вы передаете эти методы для нескольких детей и беспокоитесь о производительности, вы можете связать в конструкторе следующим образом:

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

затем использовать

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

Есть ли что-нибудь, что я могу сделать, связав функцию внутри функции render()? –

+1

Потому что я думаю, что функция привязки внутри функции render() повредит производительность (?) –

+0

Я отредактировал свой ответ и обратился к вашей проблеме – jacoballenwood

0

Если вы беспокоясь о производительности, вы можете использовать свойство класса es7. Вам не нужно вручную связывать свою функцию в конструкторе таким образом. Так что СУХОЙ!

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

Facebook говорит, что это «экспериментальный» синтаксис, но если он настроен на работу, то это тоже хорошо ! – jacoballenwood

+1

о методе привязки, я люблю использовать React Stateless Functional Component, эта статья научила меня, почему [link] (https://medium.com/@housecor/react-stateless-functional-components-nine-wins-you-might-have -overlooked-997b0d933dbC# .wt8tnld3u) –

+0

Да его экспериментальный. Но его здесь, чтобы остаться :) – FlatLander

Смежные вопросы