[javascript] js onClick 반응은 메소드에 값을 전달할 수 없습니다.

onClick 이벤트 값 속성을 읽고 싶습니다. 그러나 그것을 클릭하면 콘솔에 다음과 같은 것이 보입니다.

SyntheticMouseEvent {dispatchConfig: Object, dispatchMarker: ".1.1.0.2.0.0:1", nativeEvent: MouseEvent, type: "click", target

내 코드가 올바르게 작동합니다. 내가 실행 {column}하면 onClick 이벤트에서 볼 수는 있지만 얻을 수는 없습니다.

내 코드 :

var HeaderRows = React.createClass({
  handleSort:  function(value) {
    console.log(value);
  },
  render: function () {
    var that = this;
    return(
      <tr>
        {this.props.defaultColumns.map(function (column) {
          return (
            <th value={column} onClick={that.handleSort} >{column}</th>
          );
        })}
        {this.props.externalColumns.map(function (column) {
          // Multi dimension array - 0 is column name
          var externalColumnName = column[0];
          return ( <th>{externalColumnName}</th>);
        })}
      </tr>
    );
  }
});

onClickReact js 에서 이벤트에 값을 전달하려면 어떻게 합니까?



답변

쉬운 방법

화살표 기능을 사용하십시오.

return (
  <th value={column} onClick={() => this.handleSort(column)}>{column}</th>
);

handleSort올바른 매개 변수로 호출하는 새로운 함수가 생성됩니다 .

더 좋은 방법

하위 구성 요소로 추출하십시오.
렌더 호출에서 화살표 함수를 사용할 때의 문제는 매번 새로운 함수를 생성하여 불필요한 렌더링을 초래한다는 것입니다.

하위 컴포넌트를 작성하는 경우 핸들러를 전달하고 props를 인수로 사용할 수 있습니다. 그러면 props가 변경 될 때만 다시 렌더링됩니다 (핸들러 참조가 이제는 변경되지 않기 때문에).

하위 구성 요소

class TableHeader extends Component {
  handleClick = () => {
    this.props.onHeaderClick(this.props.value);
  }

  render() {
    return (
      <th onClick={this.handleClick}>
        {this.props.column}
      </th>
    );
  }
}

주성분

{this.props.defaultColumns.map((column) => (
  <TableHeader
    value={column}
    onHeaderClick={this.handleSort}
  />
))}

오래된 쉬운 방법 (ES5)

.bind원하는 매개 변수를 전달하는 데 사용하십시오 .

return (
  <th value={column} onClick={that.handleSort.bind(that, column)}>{column}</th>
);


답변

여기에 좋은 답변이 있으며 @Austin Greco (별도의 구성 요소가있는 두 번째 옵션)에 동의합니다.
다른 방법은 currying 입니다.
당신이 할 수있는 일은 매개 변수 (매개 변수)를 수락하고 다른 매개 변수 (이 경우 클릭 이벤트)를 허용하는 다른 함수를 반환하는 함수를 만드는 것입니다. 그때 당신은 당신이 원하는 것을 자유롭게 할 수 있습니다.

ES5 :

handleChange(param) { // param is the argument you passed to the function
    return function (e) { // e is the event object that returned

    };
}

ES6 :

handleChange = param => e => {
    // param is the argument you passed to the function
    // e is the event object that returned
};

그리고 당신은 이런 식으로 그것을 사용할 것입니다 :

<input 
    type="text" 
    onChange={this.handleChange(someParam)} 
/>

이러한 사용법의 전체 예는 다음과 같습니다.

코드 스 니펫 표시

이 방법으로 각 렌더에서 새 인스턴스를 만들 수는 없습니다.
나는이 접근법이 다른 인라인 핸들러보다 더 간결하고 읽기 쉽다는 것을 좋아합니다.

편집 :
아래 주석에서 제안한 것처럼 함수 결과를 캐시 / 메모 할 수 있습니다.

순진한 구현은 다음과 같습니다.


답변

요즘 ES6에서는 업데이트 된 답변을 사용할 수 있다고 생각합니다.

return (
  <th value={column} onClick={()=>this.handleSort(column)} >{column}</th>
);

기본적으로 (알지 못하는 사람은) onClick함수가 전달되기를 기대 bind하기 때문에 함수의 사본을 생성하기 때문에 작동합니다. 대신 원하는 함수를 호출하고 유지하는 화살표 함수 표현식을 전달할 수 있습니다 this. renderReact 에서 메소드 를 바인딩 할 필요는 없지만 어떤 이유로 든 this컴포넌트 메소드 중 하나에서 손실 되는 경우 :

constructor(props) {
  super(props);
  this.myMethod = this.myMethod.bind(this);
}


답변

[[ 댓글 에 링크하기 위한 @ E.Sundin에 대한 h / t ]]

최상위 답변 (익명 함수 또는 바인딩)은 작동하지만 map()함수에 의해 생성 된 모든 인스턴스에 대한 이벤트 핸들러의 사본을 생성하므로 가장 성능이 좋지 않습니다 .

이것은 ESLint-plugin-react 에서 수행하는 최적의 방법에 대한 설명입니다 .

아이템 목록

렌더링에서 바인드의 일반적인 사용 사례는 목록을 렌더링 할 때 목록 항목마다 별도의 콜백을 갖기위한 것입니다.

const List = props => (
      <ul>
        {props.items.map(item =>
          <li key={item.id} onClick={() => console.log(item.id)}>
            ...
          </li>
        )}
      </ul>
    );

이 방법으로 반복하지 말고 반복 된 섹션을 자체 구성 요소로 가져 오십시오.

const List = props => (
      <ul>
        {props.items.map(item =>
          <ListItem
            key={item.id}
            item={item}
            onItemClick={props.onItemClick} // assume this is passed down to List
           />
        )}
      </ul>
    );


const ListItem = props => {
  const _onClick = () => {
    console.log(props.item.id);
  }
    return (
      <li onClick={_onClick}>
        ...
      </li>
    );

});

모든 렌더링에서 (바인드 호출을 통해) 새로운 함수를 만들 필요가 없으므로 렌더링 속도가 빨라집니다.


답변

이것은 내 접근 방식이며 얼마나 나쁜지 확실하지 않습니다.

클릭 가능한 요소에서

return (
    <th value={column} onClick={that.handleSort} data-column={column}>   {column}</th>
);

그리고

handleSort(e){
    this.sortOn(e.currentTarget.getAttribute('data-column'));
}


답변

이 예는 당신과 조금 다를 수 있습니다. 그러나 이것이 당신 이이 문제에 대해 가질 수있는 최선의 해결책이라는 것을 확신 할 수 있습니다. 성능 문제가없는 솔루션을 며칠 동안 검색했습니다. 마침내 이걸 생각해 냈습니다.

class HtmlComponent extends React.Component {
  constructor() {
    super();
    this.state={
       name:'MrRehman',
    };
    this.handleClick= this.handleClick.bind(this);
  }

  handleClick(event) {
    const { param } = e.target.dataset;
    console.log(param);
    //do what you want to do with the parameter
  }

  render() {
    return (
      <div>
        <h3 data-param="value what you wanted to pass" onClick={this.handleClick}>
          {this.state.name}
        </h3>
      </div>
    );
  }
}

최신 정보

매개 변수로 간주되는 객체를 처리하려는 경우 JSON.stringify(object)문자열로 변환하고 데이터 세트에 추가하는 데 사용할 수 있습니다 .

return (
   <div>
     <h3 data-param={JSON.stringify({name:'me'})} onClick={this.handleClick}>
        {this.state.name}
     </h3>
   </div>
);


답변

class extends React.Component {
    onClickDiv = (column) => {
        // do stuff
    }
    render() {
        return <div onClick={() => this.onClickDiv('123')} />
    }
}