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


638

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 에서 이벤트에 값을 전달하려면 어떻게 합니까?



2
대신 자기를 사용하는 것을 고려하십시오. 공정이 "이"(하지 않는 것이 중요합니다 정말하지만, 각각의 자신에)와 동의어해야으로 오해의 소지가 있음을

바인드 방법을 사용하여 및 방법을 화살표 것은 우리가 onclick 이벤트에 값을 전달할 수 있습니다
Merugu 프라 샨스

답변:


1285

쉬운 방법

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

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

7
코드처럼 사용할 때 반응이 경고를 제공합니다. 코드를 onClick = {that.onClick.bind (null, column)}으로 변경
user1924375

12
사용 <a>하기 위해 이벤트를 전달해야하는 태그 와 함께 이것을 어떻게 사용 하시겠습니까?preventDefault()
Simon H

38
@SimonH 이벤트는 전달한 인수 다음에 마지막 인수로 전달됩니다 bind.
번짐

47
성능이 나쁘지 않습니까? 각 렌더에 새로운 기능이 생성되지 않습니까?
AndrewMcLagan

13
@AndrewMcLagan입니다. 나는 이것이 규칙과 가장 성능이 뛰어난 솔루션을 설명 하기 위해 이것을 발견했다 .
E. Sundin

140

여기에 좋은 답변이 있으며 @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)} 
/>

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

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

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

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


12
이것은 정답입니다. 정말 쉽게 구현할 수 있으며 다른 구성 요소를 만들거나 다르게 바인딩 할 필요가 없습니다. 감사합니다!
Tamb

29
더 나은 것처럼 보이지만 성능 측면에서 보면 커리가 실제로 도움이되지 않습니다. 동일한 매개 변수로 handleChange를 두 번 호출하면 JS 엔진이 동일한 작업을 수행하더라도 JS 객체가 별도의 객체로 간주하는 두 가지 기능을 얻을 수 있기 때문에 실제로 도움이되지 않습니다. . 따라서 여전히 다시 렌더링을받을 수 있습니다. 성능 향상을 위해 성능 변경을 얻으려면 handleChange의 결과를 캐시해야합니다. 처럼handleChange = param => cache[param] || (e => { // the function body })
travellingprog

6
이것은 당신이 @travellingprog에서 조언을 충족하면 완벽한 해답입니다
llioor

2
누구나이 캐싱 메커니즘의 작동 방식을 설명하거나 링크를 제공 할 수 있습니까? 감사.
Sadok Mtir

2
아름답고 깔끔합니다!
Hatem Alimam

117

요즘 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);
}

10
render()React에 의해 호출되므로 바인딩 할 필요가 없습니다 . 어떤 것이 bind든, 이벤트 핸들러에 필요하며 화살표를 사용하지 않을 때만 필요합니다 .
Dan Abramov

1
@ DanAbramov 나는 당신이 맞다고 생각하지만, 바인딩 렌더링을 암시 적으로 장려하지 않는 예제로 업데이트 된 경우에 대비하여 포함 시켰습니다.
aikeru

3
생성자 에게 전달 props하는 것이 가장 좋 super()거나 this.props생성 중에 정의되지 않아 혼란 스러울 수 있습니다.
Dan Abramov

2
무엇을 달성하기 위해? 함수형 컴포넌트 내에 핸들러를 정의하고 전달할 수 있습니다. 렌더링마다 함수가 다르므로 성능 문제가 있다고 프로파일 러로 결정한 경우 (실제로 확실하다고 확신하는 경우에만) 클래스를 대신 사용해보십시오.
Dan Abramov

1
@ me-me 예, Babel에서 최신 JavaScript를 사용하도록 선택하는 경우 클래스에서 속성을 선언 foo = () => {...}한 다음 <button onClick={this.foo}...이 방법으로 babel을 사용하는 경우 화살표 함수를 포함하는 유일한 이유를 렌더링 해야합니다. render () 메소드 범위에만 존재하는 일부 변수를 캡처하려는 경우입니다 (이벤트는 전달할 수 있으며 적용 할 수 없음).
aikeru

73

[[ 댓글 에 링크하기 위한 @ 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>
    );

});

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


반응은 해당 함수를 호출 / 적용으로 호출 한 다음 후드 아래에서 호출하고 내부적으로 바인드를 사용하지 않습니까?
aikeru

1
상태 비 저장 구성 요소를 사용하여이 작업을 수행하는 방법이 있습니까?
Carlos Martinez

2
@CarlosMartinez 좋은 눈, 나는 예제를 업데이트했다. 일반적으로 구성 요소가을 사용하지 않으면 this.stateSFC와 안전하게 교체 할 수 있습니다.
Brandon

3
흠, 나는 이것이 어떻게 더 성능이 좋은지 모르겠습니까? 매번 ListItem 함수가 호출되지 않으므로 _onClick 함수가 렌더링마다 생성됩니다.
Mattias Petter Johansson 21 년 4

1
나는 여기 전문가와는 거리가 멀지 만 이해하는 것처럼 '올바른'패턴에는 처리기의 인스턴스가 하나 뿐이며 구성 요소의 인스턴스가 호출하는 경우에 대한 소품이 전달됩니다. 바인드 예제 (즉, '잘못된'패턴)에는 모든 인스턴스화 된 구성 요소마다 하나의 핸들러 인스턴스가 있습니다. 그것은 같은 함수를 30 번 작성하는 것과 같은 기능을 한 번 작성하고 필요한 곳에서 호출하는 것과 같은 메모리입니다.
Brandon

25

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

클릭 가능한 요소에서

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

그리고

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

이것은 내가 생각한 접근법이며 약간 해키 느낌이 들지만 새로운 구성 요소를 만드는 것을 피합니다. getAttribute가 별도의 구성 요소를 가져 오는 것과 비교하여 성능이 좋거나 나쁜지 확실하지 않습니다.
kamranicus

2
나는 그것이 매우 간단하기 때문에 좋은 해결책이라고 생각합니다. 그러나 객체를 원한다면 작동하지 않는 문자열 값에서만 작동합니다.
Stephane L

객체의 encodeURIComponent(JSON.stringify(myObj))경우을 수행 한 다음 구문 분석해야합니다 JSON.parse(decodeURIComponent(myObj)). 함수의 경우 eval 또는 new Function () 없이는 작동하지 않을 것이라고 확신합니다. 둘 다 피해야합니다. 이러한 이유로 나는 데이터 속성을 사용하여 React / JS의 데이터를 전달하지 않습니다.
Solvitieg

나는 이것을 자주 사용하지 않고 사소한 일에만 사용한다고 덧붙이고 싶습니다. 그러나 일반적으로 구성 요소를 만들고 소품으로 데이터를 전달합니다. 그런 다음 새 구성 요소 내부의 클릭을 처리하거나 onClick 함수를 구성 요소에 전달하십시오. Brandon의 답변 에서처럼
Santiago Ramirez

1
e.currentTarget.dataset.column : 데이터 집합 (IE11 포함)의 최신 브라우저에서이 길에 직접 액세스 할 수
gsziszi

17

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

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

1
전달 된 데이터가 객체 인 경우에는 작동하지 않습니다
SlimSim

JSON.stringify를 사용하여 문제를 해결하십시오. @SlimSim. 트릭해야한다고
hannad 레흐만

이 문제에 JSON.stringify를 사용해야하는 경우 올바른 방법이 아닐 수 있습니다. 스트링 화 프로세스에는 많은 메모리가 필요합니다.
KFE

대부분의 경우 ID를 매개 변수로만 전달하고 소스 객체에서 해당 ID를 기반으로 객체 세부 정보를 가져옵니다. 왜 그리고 어떻게 많은 메모리가 필요합니까, JSON stringify가 느리다는 것을 알고 있습니다. 그러나 클릭 Fn은 비동기 적이며 일단 구성되면 dom에 전혀 영향을 미치지 않습니다.
hannad rehman

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

2
동일-각 렌더링에서 새로운 DOM. 따라서 React는 매번 DOM을 업데이트합니다.
Alex Shwarc

4

.bindES6 과 관련되지 않은 또 다른 옵션 은 처리기와 함께 하위 구성 요소를 사용하여 필요한 소품으로 부모 처리기를 호출하는 것입니다. 다음은 예제입니다 (작업 예제에 대한 링크는 다음과 같습니다).

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

// A child component to pass the props back to the parent handler
var TableHeader = React.createClass({
  propTypes: {
    value: React.PropTypes.string,
    onClick: React.PropTypes.func
  },
  render: function () {
    return (
      <th value={this.props.value} onClick={this._handleClick}
        {this.props.children}
      </th>
    )        
  },
  _handleClick: function () {
    if (this.props.onClick) {
      this.props.onClick(this.props.value);
    }
  }
});

기본 아이디어는 부모 구성 요소가 onClick함수를 자식 구성 요소에 전달하는 것입니다. 자식 구성 요소는 onClick함수를 호출하고 props전달 된 모든 (및 event)에 액세스 할 수 있으므로 event부모 onClick함수 내에서 값이나 다른 소품 을 사용할 수 있습니다 .

여기의 데모 CodePen을 행동에서이 방법을 나타내는.


4

e.preventDefault () 호출을 포함하여 OP의 질문에 대답하기위한 대체 시도 :

렌더링 된 링크 ( ES6 )

<a href="#link" onClick={(e) => this.handleSort(e, 'myParam')}>

구성 요소 기능

handleSort = (e, param) => {
  e.preventDefault();
  console.log('Sorting by: ' + param)
}

4

나는 이것이 파티에 꽤 늦었다는 것을 알고 있지만 훨씬 간단한 솔루션이 많은 유스 케이스를 충족시킬 수 있다고 생각합니다.

    handleEdit(event) {
        let value = event.target.value;
    }

    ...

    <button
        value={post.id}
        onClick={this.handleEdit} >Edit</button>

data-속성을 사용할 수도 있다고 가정 합니다.

단순하고 의미 적입니다.


4

간단히 이와 같은 함수를 작성하십시오

  function methodName(params) {
    //the thing  you wanna do
  }

필요한 곳에 전화하십시오

<Icon onClick = {() => {methodName (theParamsYouwantToPass); }} />


3

를 사용하는 경우 간단하게 수행 할 수 있습니다 ES6.

export default class Container extends Component {
  state = {
    data: [
        // ...
    ]
  }

  handleItemChange = (e, data) => {
      // here the data is available 
      // ....
  }
  render () {
     return (
        <div>
        {
           this.state.data.map((item, index) => (
              <div key={index}>
                  <Input onChange={(event) => this.handItemChange(event, 
                         item)} value={item.value}/>
              </div>
           ))
        }
        </div>
     );
   }
 }

3

아래 설명과 같이 count를 매개 변수로 main에서 subcomponent로 전달하여 객체의 총 개수를 표시합니다.

여기 MainComponent.js가 있습니다

import React, { Component } from "react";

import SubComp from "./subcomponent";

class App extends Component {

  getTotalCount = (count) => {
    this.setState({
      total: this.state.total + count
    })
  };

  state = {
    total: 0
  };

  render() {
    const someData = [
      { name: "one", count: 200 },
      { name: "two", count: 100 },
      { name: "three", count: 50 }
    ];
    return (
      <div className="App">
        {someData.map((nameAndCount, i) => {
          return (
            <SubComp
              getTotal={this.getTotalCount}
              name={nameAndCount.name}
              count={nameAndCount.count}
              key={i}
            />
          );
        })}
        <h1>Total Count: {this.state.total}</h1>
      </div>
    );
  }
}

export default App;

그리고 여기 SubComp.js

import React, { Component } from 'react';
export default class SubComp extends Component {

  calculateTotal = () =>{
    this.props.getTotal(this.props.count);
  }

  render() {
    return (
      <div>
        <p onClick={this.calculateTotal}> Name: {this.props.name} || Count: {this.props.count}</p>
      </div>
    )
  }
};

위의 구현을 시도하면 모든 DOM 메소드의 reactjs에서 전달 매개 변수가 작동하는 정확한 시나리오를 얻을 수 있습니다.


3

여기에 허용 된 답변을 바탕 으로이 목적으로 재사용 할 수있는 래퍼 구성 요소를 작성했습니다. 그러나 문자열을 전달하기 만하면 데이터 속성을 추가하고 e.target.dataset에서 읽을 수 있습니다 (다른 사람들이 제안한 것처럼). 기본적으로 내 래퍼는 함수 인 모든 prop에 바인딩하고 'on'으로 시작하고 다른 모든 이벤트 인수 후에 데이터 prop를 자동으로 호출자에게 다시 전달합니다. 성능 테스트를 수행하지는 않았지만 클래스를 직접 만들지 않을 수 있으며 다음과 같이 사용할 수 있습니다.

const DataButton = withData('button')
const DataInput = withData('input');

또는 구성 요소 및 기능

const DataInput = withData(SomeComponent);

또는 원하는 경우

const DataButton = withData(<button/>)

컨테이너 외부 (수입품 근처)

컨테이너의 사용법은 다음과 같습니다.

import withData from './withData';
const DataInput = withData('input');

export default class Container extends Component {
    state = {
         data: [
             // ...
         ]
    }

    handleItemChange = (e, data) => {
        // here the data is available 
        // ....
    }

    render () {
        return (
            <div>
                {
                    this.state.data.map((item, index) => (
                        <div key={index}>
                            <DataInput data={item} onChange={this.handleItemChange} value={item.value}/>
                        </div>
                    ))
                }
            </div>
        );
    }
}

다음은 래퍼 코드 'withData.js입니다.

import React, { Component } from 'react';

const defaultOptions = {
    events: undefined,
}

export default (Target, options) => {
    Target = React.isValidElement(Target) ? Target.type : Target;
    options = { ...defaultOptions, ...options }

    class WithData extends Component {
        constructor(props, context){
            super(props, context);
            this.handlers = getHandlers(options.events, this);        
        }

        render() {
            const { data, children, ...props } = this.props;
            return <Target {...props} {...this.handlers} >{children}</Target>;
        }

        static displayName = `withData(${Target.displayName || Target.name || 'Component'})`
    }

    return WithData;
}

function getHandlers(events, thisContext) {
    if(!events)
        events = Object.keys(thisContext.props).filter(prop => prop.startsWith('on') && typeof thisContext.props[prop] === 'function')
    else if (typeof events === 'string')
        events = [events];

    return events.reduce((result, eventType) => {
        result[eventType] = (...args) => thisContext.props[eventType](...args, thisContext.props.data);
        return result;
    }, {});
}

2

JSX onClick Events에 대한 제안은 3 개 미만입니다.

  1. 실제로 코드에서 .bind () 또는 Arrow 함수를 사용할 필요는 없습니다. 코드에서 간단하게 사용할 수 있습니다.

  2. onClick 이벤트를 th (또는 ul)에서 tr (또는 li)로 이동하여 성능을 향상시킬 수도 있습니다. 기본적으로 n li 요소에 대해 n 개의 "이벤트 리스너"가 있습니다.

    So finally code will look like this:
    <ul onClick={this.onItemClick}>
        {this.props.items.map(item =>
               <li key={item.id} data-itemid={item.id}>
                   ...
               </li>
          )}
    </ul>

    // 아래와 같이 메소드 item.id에서 액세스 할 수 있습니다 onItemClick.

    onItemClick = (event) => {
       console.log(e.target.getAttribute("item.id"));
    }
  3. ListItem 및 List에 대해 별도의 React Component를 작성하는 위의 접근 방식에 동의합니다. 이렇게하면 코드가 좋아 보이지만 1000 개의 li이 있으면 1000 개의 이벤트 리스너가 작성됩니다. 많은 이벤트 리스너가 없어야합니다.

    import React from "react";
    import ListItem from "./ListItem";
    export default class List extends React.Component {
    
        /**
        * This List react component is generic component which take props as list of items and also provide onlick
        * callback name handleItemClick
        * @param {String} item - item object passed to caller
        */
        handleItemClick = (item) => {
            if (this.props.onItemClick) {
                this.props.onItemClick(item);
            }
        }
    
        /**
        * render method will take list of items as a props and include ListItem component
        * @returns {string} - return the list of items
        */
        render() {
            return (
                <div>
                  {this.props.items.map(item =>
                      <ListItem key={item.id} item={item} onItemClick={this.handleItemClick}/>
                  )}
                </div>
            );
        }
    
    }
    
    
    import React from "react";
    
    export default class ListItem extends React.Component {
        /**
        * This List react component is generic component which take props as item and also provide onlick
        * callback name handleItemClick
        * @param {String} item - item object passed to caller
        */
        handleItemClick = () => {
            if (this.props.item && this.props.onItemClick) {
                this.props.onItemClick(this.props.item);
            }
        }
        /**
        * render method will take item as a props and print in li
        * @returns {string} - return the list of items
        */
        render() {
            return (
                <li key={this.props.item.id} onClick={this.handleItemClick}>{this.props.item.text}</li>
            );
        }
    }

1
전달해야하는 데이터가 개체 인 경우에는 작동하지 않습니다. 이 속성은 문자열에서만 작동합니다. 또한 get 속성을 통해 dom에서 읽는 것이 아마도 더 비싼 작업 일 것입니다.
SlimSim

2

onclick 이벤트 값에 대한 코드를 두 가지 방법으로 메소드에 추가했습니다. 1 . bind 메소드 사용 2. arrow (=>) 메소드 사용. handlesort1 및 handlesort 메소드 참조

var HeaderRows  = React.createClass({
    getInitialState : function() {
      return ({
        defaultColumns : ["col1","col2","col2","col3","col4","col5" ],
        externalColumns : ["ecol1","ecol2","ecol2","ecol3","ecol4","ecol5" ],

      })
    },
    handleSort:  function(column,that) {
       console.log(column);
       alert(""+JSON.stringify(column));
    },
    handleSort1:  function(column) {
       console.log(column);
       alert(""+JSON.stringify(column));
    },
    render: function () {
        var that = this;
        return(
        <div>
            <div>Using bind method</div>
            {this.state.defaultColumns.map(function (column) {
                return (
                    <div value={column} style={{height : '40' }}onClick={that.handleSort.bind(that,column)} >{column}</div>
                );
            })}
            <div>Using Arrow method</div>

            {this.state.defaultColumns.map(function (column) {
                return (
                    <div value={column} style={{height : 40}} onClick={() => that.handleSort1(column)} >{column}</div>

                );
            })}
            {this.state.externalColumns.map(function (column) {
                // Multi dimension array - 0 is column name
                var externalColumnName = column;
                return (<div><span>{externalColumnName}</span></div>
                );
            })}

        </div>);
    }
});

2

다음은 onClick 이벤트에 값을 전달하는 예입니다.

es6 구문을 사용했습니다. 클래스 컴포넌트에서 화살표 함수는 자동으로 바인딩되지 않으므로 생성자에서 명시 적으로 바인딩하는 것을 기억하십시오.

class HeaderRows extends React.Component {

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

    handleSort(value) {
        console.log(value);
    }

    render() {
        return(
            <tr>
                {this.props.defaultColumns.map( (column, index) =>
                    <th value={ column } 
                        key={ index } 
                        onClick={ () => this.handleSort(event.target.value) }>
                        { column }
                    </th>
                )}

                {this.props.externalColumns.map((column, index)  =>
                    <th value ={ column[0] }
                        key={ index }>
                        {column[0]}
                    </th>
                )}
            </tr>
         );
    }
}

2

메소드를 React의 클래스 인스턴스에 바인딩해야한다고 생각합니다. React의 모든 메소드를 바인딩하기 위해 생성자를 사용하는 것이 더 안전합니다. 매개 변수를 메서드에 전달하면 첫 번째 매개 변수가 메서드의 'this'컨텍스트를 바인딩하는 데 사용되므로 메서드 내부의 값에 액세스 할 수 없습니다.


2
1. You just have to use an arrow function in the Onclick event like this: 

<th value={column} onClick={() => that.handleSort(theValue)} >{column}</th>

2.Then bind this in the constructor method:
    this.handleSort = this.handleSort.bind(this);

3.And finally get the value in the function:
  handleSort(theValue){
     console.log(theValue);
}

2

매우 쉬운 방법이 있습니다.

 onClick={this.toggleStart('xyz')} . 
  toggleStart= (data) => (e) =>{
     console.log('value is'+data);  
 }

2
class TableHeader extends Component {
  handleClick = (parameter,event) => {
console.log(parameter)
console.log(event)

  }

  render() {
    return (
      <button type="button" 
onClick={this.handleClick.bind(this,"dataOne")}>Send</button>
    );
  }
}

4
이 코드는 문제를 해결할 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 실제로 도움이됩니다. 앞으로 독자에게 질문에 대한 답변을 제공하고 있으며 해당 사람들이 귀하의 코드 제안 이유를 모를 수도 있습니다.
Shree

2

이 질문에 아무데도 나오지 않지만 .bind트릭을 할 것이라고 생각 합니다. 아래에서 샘플 코드를 찾으십시오.

const handleClick = (data) => {
    console.log(data)
}

<button onClick={handleClick.bind(null, { title: 'mytitle', id: '12345' })}>Login</button>

1

화살표 기능 사용 :

2 단계를 설치해야합니다.

npm은 babel-preset-stage-2를 설치합니다.

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            value=0
        }
    }

    changeValue = (data) => (e) => {
        alert(data);  //10
        this.setState({ [value]: data })
    }

    render() {
        const data = 10;
        return (
            <div>
                <input type="button" onClick={this.changeValue(data)} />
            </div>
        );
    }
}
export default App; 

0

이것을 처리하는 세 가지 방법이 있습니다 :-

  1. 생성자에서 메소드를 다음과 같이 바인딩하십시오.

    export class HeaderRows extends Component {
       constructor() {
           super();
           this.handleSort = this.handleSort.bind(this);
       }
    }
  2. 화살표 기능을 다음과 같이 작성하는 동안 사용하십시오.

    handleSort = () => {
        // some text here
    }
  3. 세 번째 방법은 이것입니다 :-

    <th value={column} onClick={() => that.handleSort} >{column}</th>

0

다음과 같이 코드를 사용할 수 있습니다.

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

preventDefault()핸들 함수에서 와 같은 이벤트 메소드를 사용 하거나 같은 목표 값 또는 이름을 얻으려는 경우 여기 e는 이벤트 오브젝트 e.target.name입니다.


0

param을 태그의 속성으로 전달하는 솔루션이 상당히 합리적이라는 것을 알았습니다.

그러나 다음과 같은 제한이 있습니다.

  • 목록 항목에 다른 태그가있는 경우 제대로 작동하지 않습니다 (따라서 event.target이 의도 한 것과 다를 수 있음)
  • Param은 문자열 만 될 수 있습니다. 직렬화 및 역 직렬화가 필요합니다.

그래서 내가이 라이브러리를 생각해 냈습니다 : react-event-param

그것:

  • 필요할 때마다 부모에서 필요한 속성을 검색하여 어린이 문제를 해결합니다.
  • 매개 변수를 자동으로 직렬화 및 직렬화 해제
  • 설정 및 가져 오기의 논리를 캡슐화합니다. 매개 변수 이름을 엉망으로 만들 필요가 없습니다.

사용 예 :

import { setEventParam, getEventParam } from "react-event-param";

class List extends Component {
  onItemClick = e => {
    const index = getEventParam(e.target);
    // Do something with index
  };

  render() {
    return (
      <ul>
        {this.props.items.map((itemText, index) => (
          <li
            key={index}
            {...setEventParam(index)}
            onClick={this.onItemClick}
          >
            {{ itemText }}
          </li>
        ))}
      </ul>
    );
  }
}

export default List;

0

진공 상태에서는 많은 성능 고려 사항이있었습니다.
이 핸들러의 문제점은 소품에 이름을 지정할 수없는 주장을 통합하기 위해 카레를 만들어야한다는 것입니다.
즉, 구성 요소에는 클릭 가능한 각 요소마다 핸들러가 필요합니다. 몇 개의 버튼에 대해서는 이것이 문제가 아니라는 것에 동의합시다.
수십 개의 열과 수천 개의 행이있는 테이블 형식 데이터를 처리 할 때 문제가 발생합니다. 거기에서 많은 핸들러를 작성하는 데 따른 영향을 알 수 있습니다.

사실은 하나만 필요합니다.
처리기를 테이블 수준 (또는 UL 또는 OL ...)으로 설정하고 클릭이 발생하면 이벤트 객체에서 사용 가능한 데이터를 사용하여 클릭 한 셀을 알 수 있습니다.

nativeEvent.target.tagName
nativeEvent.target.parentElement.tagName 
nativeEvent.target.parentElement.rowIndex
nativeEvent.target.cellIndex
nativeEvent.target.textContent

태그 이름 필드를 사용하여 유효한 요소에서 클릭이 발생했는지 확인합니다. 예를 들어 바닥 글의 클릭은 무시합니다.
rowIndex 및 cellIndex는 클릭 한 셀의 정확한 위치를 제공합니다.
텍스트 내용은 클릭 한 셀의 텍스트입니다.

이렇게하면 셀의 데이터를 처리기에 전달할 필요가 없으며 셀프 서비스 할 수 있습니다.
더 많은 데이터, 표시되지 않는 데이터가 필요한 경우 dataset 특성 또는 숨겨진 요소를 사용할 수 있습니다.
간단한 DOM 탐색으로 모든 것이 가능합니다.
PC가 훨씬 쉽게 습격되기 때문에 그 이후로 HTML에서 사용되었습니다.


0

이벤트 처리기에서 매개 변수를 전달하는 방법에는 두 가지가 있으며 일부는 다음과 같습니다.

화살표 함수를 사용하여 이벤트 핸들러를 감싸고 매개 변수를 전달할 수 있습니다.

<button onClick={() => this.handleClick(id)} />

위의 예는 호출과 동일 .bind하거나 명시 적으로 bind 를 호출 할 수 있습니다.

<button onClick={this.handleClick.bind(this, id)} />

이 두 가지 방법 외에도 카레 함수로 정의 된 함수에 인수를 전달할 수도 있습니다.

handleClick = (id) => () => {
    console.log("Hello, your ticket number is", id)
};

<button onClick={this.handleClick(id)} />

-1

클로저를 사용하면 깨끗한 솔루션이됩니다.

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

handleSort 함수는 값 열이 이미 설정된 함수를 반환합니다 .

handleSort: function(value) { 
    return () => {
        console.log(value);
    }
}

사용자가 th를 클릭하면 익명 함수가 올바른 값으로 호출됩니다.

예 : https://stackblitz.com/edit/react-pass-parameters-example


-2

간단한 변경이 필요합니다 :

사용하다 <th value={column} onClick={that.handleSort} >{column}</th>

대신에 <th value={column} onClick={that.handleSort} >{column}</th>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.