React js onClick can't pass value to method

后端 未结 30 1696
北荒
北荒 2020-11-22 07:05

I want to read the onClick event value properties. But when I click on it, I see something like this on the console:

SyntheticMouseEvent {dispatchConfig: Ob         


        
相关标签:
30条回答
  • 2020-11-22 07:25

    You can simply do it if you are using 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>
         );
       }
     }
    
    0 讨论(0)
  • 2020-11-22 07:27

    Easy Way

    Use an arrow function:

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

    This will create a new function that calls handleSort with the right params.

    Better Way

    Extract it into a sub-component. The problem with using an arrow function in the render call is it will create a new function every time, which ends up causing unneeded re-renders.

    If you create a sub-component, you can pass handler and use props as the arguments, which will then re-render only when the props change (because the handler reference now never changes):

    Sub-component

    class TableHeader extends Component {
      handleClick = () => {
        this.props.onHeaderClick(this.props.value);
      }
    
      render() {
        return (
          <th onClick={this.handleClick}>
            {this.props.column}
          </th>
        );
      }
    }
    

    Main component

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

    Old Easy Way (ES5)

    Use .bind to pass the parameter you want, this way you are binding the function with the Component context :

    return (
      <th value={column} onClick={this.handleSort.bind(this, column)}>{column}</th>
    );
    
    0 讨论(0)
  • 2020-11-22 07:28

    Using arrow function :

    You must install stage-2:

    npm install 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 讨论(0)
  • 2020-11-22 07:29
    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);
    }
    
    0 讨论(0)
  • 2020-11-22 07:32

    Theres' a very easy way.

     onClick={this.toggleStart('xyz')} . 
      toggleStart= (data) => (e) =>{
         console.log('value is'+data);  
     }
    
    0 讨论(0)
  • 2020-11-22 07:33

    I wrote a wrapper component that can be reused for this purpose that builds on the accepted answers here. If all you need to do is pass a string however, then just add a data-attribute and read it from e.target.dataset (like some others have suggested). By default my wrapper will bind to any prop that is a function and starts with 'on' and automatically pass the data prop back to the caller after all the other event arguments. Although I haven't tested it for performance, it will give you the opportunity to avoid creating the class yourself, and it can be used like this:

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

    or for Components and functions

    const DataInput = withData(SomeComponent);
    

    or if you prefer

    const DataButton = withData(<button/>)
    

    declare that Outside your container (near your imports)

    Here is usage in a container:

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

    Here is the wrapper code '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;
        }, {});
    }
    
    0 讨论(0)
提交回复
热议问题