admin管理员组

文章数量:1398216

how to get the 'e.key' of li element in react.js?

I just can't get the event target e.key, what's wrong with this?

Anybody can help me with this problem?

online playaround link!

// import React, {Component} from 'react';
// import PropTypes from 'prop-types';

class RMT extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: this.props.data || []
        };
    }
    // 递归调用
    markNode = (data) => {
        let nodes;
        if (Object.prototype.toString.call(data) == "[object Array]") {
            nodes = data.map(
                (item) => {
                    let node = (
                        <li
                            key={this.count++}
                            style={{color: 'red'}}
                            onClick={(e) => this.props.onClick(e)}
                            >
                            <span>{item.text}</span>
                        </li>
                    );
                    if (item.children && item.children.length) {
                        node = (
                            <li
                                key={this.count++}
                                style={{color: 'green', marginLeft: '10px'}}
                                onClick={(e) => this.props.onClick(e)}
                                >
                                <span>{item.text}</span>
                                {this.markNode(item.children)}
                            </li>
                        );
                    }
                    return node;
                }
            );
        }
        return (
            <ul style={{border: '1px solid red'}} onClick={this.props.onClick}>
                {nodes}
            </ul>
        );
    };
    render() {
        this.count = 0;
        return(
            this.markNode(this.state.data)
        );
    }
}

export {RMT};
export default RMT;

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            // 
        };
    }
    onClick = (e) => {
        // 阻止事件的默认行为,防止事件冒泡!
        e.preventDefault();
        e.stopPropagation();
        // alert(`e`, e.key);
        console.log('e.key', e.key);
        console.log('e.text', e.text);
        console.log('e.innerHTML', e.innerHTML);
        console.log('e.innerText', e.innerText);
    };
    render () {
        const datas = [
            {
                text: 'root',
                children: [
                    {
                        text: 'chlid1',
                        children: [
                            {
                                text: 'chlid3'
                            }
                        ]
                    }
                ]
            }
        ];
        return (
            <div>
                <RMT data={datas} onClick={this.onClick}/>
            </div>
        );
    }
}

export default App;

ReactDOM.render(
    <div>
        <App />
    </div>
    , mountNode
);
<script src=".1.0/react.min.js"></script>
<script src=".1.0/react-dom.min.js"></script>

how to get the 'e.key' of li element in react.js?

I just can't get the event target e.key, what's wrong with this?

Anybody can help me with this problem?

online playaround link!

https://jsplete./repl

// import React, {Component} from 'react';
// import PropTypes from 'prop-types';

class RMT extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: this.props.data || []
        };
    }
    // 递归调用
    markNode = (data) => {
        let nodes;
        if (Object.prototype.toString.call(data) == "[object Array]") {
            nodes = data.map(
                (item) => {
                    let node = (
                        <li
                            key={this.count++}
                            style={{color: 'red'}}
                            onClick={(e) => this.props.onClick(e)}
                            >
                            <span>{item.text}</span>
                        </li>
                    );
                    if (item.children && item.children.length) {
                        node = (
                            <li
                                key={this.count++}
                                style={{color: 'green', marginLeft: '10px'}}
                                onClick={(e) => this.props.onClick(e)}
                                >
                                <span>{item.text}</span>
                                {this.markNode(item.children)}
                            </li>
                        );
                    }
                    return node;
                }
            );
        }
        return (
            <ul style={{border: '1px solid red'}} onClick={this.props.onClick}>
                {nodes}
            </ul>
        );
    };
    render() {
        this.count = 0;
        return(
            this.markNode(this.state.data)
        );
    }
}

export {RMT};
export default RMT;

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            // 
        };
    }
    onClick = (e) => {
        // 阻止事件的默认行为,防止事件冒泡!
        e.preventDefault();
        e.stopPropagation();
        // alert(`e`, e.key);
        console.log('e.key', e.key);
        console.log('e.text', e.text);
        console.log('e.innerHTML', e.innerHTML);
        console.log('e.innerText', e.innerText);
    };
    render () {
        const datas = [
            {
                text: 'root',
                children: [
                    {
                        text: 'chlid1',
                        children: [
                            {
                                text: 'chlid3'
                            }
                        ]
                    }
                ]
            }
        ];
        return (
            <div>
                <RMT data={datas} onClick={this.onClick}/>
            </div>
        );
    }
}

export default App;

ReactDOM.render(
    <div>
        <App />
    </div>
    , mountNode
);
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>

Share Improve this question asked Jul 18, 2017 at 9:31 user8202629user8202629 2
  • What do you expect the value of e.key on onClick to be? Are you looking for onKeyDown? – Fabian Schultz Commented Jul 18, 2017 at 9:35
  • try this console.log('e.key', e.key || e.which); not all browsers support e.key AFAIK – StudioTime Commented Jul 18, 2017 at 9:36
Add a ment  | 

4 Answers 4

Reset to default 3

A few things to note here that will hopefully point you in the right direction:

1) It is ambiguous to what key you refer. In React a ponent's key is not publicly accessible, this is by design. However as you have logged e.key you may be trying to access the keyboard key of the event itself - however this is not present on a mouse event, only a keyboard event.

2) Your onClick handler that logs out values does not act in exactly the same manner as a standard DOM event, the event actually es from React's own internal synthetic event system, and the scope of your handler (ie this) is the class to which it is lexically bound, not as in a standard DOM event where the scope is the element that triggered it (your App.onClick is lexically bound by the arrow function to the instance of App)

You can still access the wrapped event, and the DOM node that caused it by properties of Reacts own synthetic event...

onClick = (e) => { // types are... e: SyntheticEvent<MouseEvent> , this: App
    e.preventDefault()
    e.stopPropagation()
    // you can access the native DOM event this wraps via the `nativeEvent` to call methods or access event properties that React does not proxy. This is not remended though as React has done a lot of work to consolidate any browser quirks, which accessing native event like this would negate, so you'ld have to handle that yourself
    e.nativeEvent.stopImmediatePropagation()

    // access the actual DOM node that triggered the event via `target`
    console.log(e.target.innerHTML);
    // access the DOM node that the event is currently the current event phase is acting upon via `currentTarget`
    console.log(e.target.innerHTML);

    // if you REALLY need some data to be available via the DOM itself, then you can it via the DOM node's `data` attributes (ie data-nic-cage={someString}, and access it like so...
    console.log(e.target.dataset.nicCage)
}

3) When assigning your key you are incrementing this.count which means that no 2 keys will be the same on subsequent renders. Your render function is impure, and will cause React to be unable to reconcile subsequent rendered child ponents to current child ponents, and instead always unmount then remount new ones causing unnecessary re-renders and losing child state - hurting performance, and potentially introducing bugs in the child ponents. Unless it has a greater meaning to you (ie forcing reanimation to occur) then you can just pass the map index (although a stable id would be preferable but I can't see anything suitable there on item).

data.map((item, i) => <li key={i} /*other props*/ />)

i don't think you can access key attribute in react. If you need to pass the value, you can use another prop name such as indexKey or anything else.

You need bind your function onClick in App ponent

    class App extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                // 
            };
            this.onClick = this.onClick.bind(this);
        }

this is a demo to show that, in react.js you can't access e.key directly!

                <Message
                    key={index}
                    indexkey={index}
                    text={message.text}
                    color={message.color}
                    xyzClick={this.props.xyzClick}
                />
                this.props.indexkey = {this.props.indexkey}

online playground!

https://jsplete./repl

// props is an object!


// message.text => array of objects
class MessageList extends React.Component {
    getChildren = () => {
        //
    }
    render() {
        const children = this.props.messages.map(
            (message, index) => {
                //console.log(`message = `, message);
            		console.log(`index = `, index);
                //console.log(`typeof index = `, typeof index);
                let xindex = 'id_' + index; 
                console.log(`xindex = `, xindex);
                //console.log(`typeof xindex = `, typeof xindex);
                return(
                    <Message
                        key={index}
                        text={message.text}
                        color={message.color}
                        xyzClick={this.props.xyzClick}
                    />
                );
            }
        );
        const styles = {
        		css1: {
            		color: 'red'
            },
            css2: {
            		color: '#0f0'
            }
        }
      	return(
            <div>
                children = {children}
                <hr />
                <div>
                    BAD: <br />
                    {/* this.props = {this.props} */}
                    <div style={styles.css1}>
                        this.props.children = {this.props.color}
                    </div>
                    {/* this.props.arr = {this.props.arr} */}
                    {/* this.props.obj = {this.props.obj} */}
                    <br />
                    <p style={styles.css2}>
                        Object Error, need using map items to item
                    </p>
                </div>
            </div>
        );
    }
}

// text={message.text} => message object
class Message extends React.Component {
    render() {
    		//console.log(`this.props.text = `, this.props.text);
        //console.log(`this.props.key= `, this.props.key);
        let style = `
        		color: red;
            font-size: 23px;
        `;
        if(this.props.key === undefined){
        		//alert(`smg!`);
            console.log(`%c this.props.key= \n`, style, this.props.key);
        }
        return (
            <div>
                <hr />
                this.props.key = {this.props.key}
                <br />
                this.props.text = {this.props.text}
                <br />
                this.props.color = <span style={{backgroundColor: this.props.color}}>{this.props.color}</span>
                <br />
                <Button color={this.props.color} xyzClick={this.props.xyzClick}>
                    <span style={{color: '#fff'}}>Delete</span>
                </Button>
            </div>
        );
    }
}

// props.children === <span style={{color: '#fff'}}>Delete</span> ??? 
class Button extends React.Component {
    render() {
        return (
            <button
                style={{background: this.props.color}} 
                onClick={(e) => this.props.xyzClick(e)} 
                >
                {this.props.children}
            </button>
        );
    }
}




const text = [
    {
    text: "text 1",
    color: "red"
    },
    {
    text: "text 2",
    color: "blue"
    },
    {
    text: "text 3",
    color: "grey"
    },
    {
    text: "text 4",
    color: "green"
    },
    {
    text: "text 5",
    color: "#f0f"
    }
];
const color = "green";
const ArrayTest = [1, 2, 3];
const ObjectTest = {"key": "value"};

class App extends React.Component{
    constructor(props){
        super(props);
        this.state  = {
            showSate: false
        };
    }
    setModalVisible = (value) => {
        console.log(`showSate`, this.state.showSate);
        console.log(`value`, value);
        this.setState({
            showSate: value
        });
        // 状态更新可能是异步的
        setTimeout(() => {
        		console.log(`showSate`, this.state.showSate);
        });
    };
  	XC = (e) => {
      	let m = e.toString();
      	console.log(e, m);
      	return alert(`e.toString(); =\n`, m);
  	};
  render(){
      return(
          <div>
               <div>
                   <button onClick={() => console.log(`smg`)}>
                       onClick
                   </button>
                   <button onClick={()=>this.setModalVisible(true)}>
                       showModal{this.state.showSate}
                   </button>
               </div>
               <MessageList
                   messages={text}
                   color={color}
                   arr={ArrayTest}
                   obj={ObjectTest}
                   xyzClick={this.XC}/>
          </div>
      );
    }
};



export default App;

ReactDOM.render(
    <App />,
    mountNode
);



/********************************* new version *************************************/

// props is an object!


// message.text => array of objects
class MessageList extends React.Component {
    getChildren = () => {
        //
    }
    render() {
        const children = this.props.messages.map(
            (message, index) => {
                //console.log(`message = `, message);
            		console.log(`index = `, index);
                //console.log(`typeof index = `, typeof index);
                let xindex = 'id_' + index; 
                console.log(`xindex = `, xindex);
                //console.log(`typeof xindex = `, typeof xindex);
                return(
                    <Message
                        key={index}
                        indexkey={index}
                        text={message.text}
                        color={message.color}
                        xyzClick={this.props.xyzClick}
                    />
                );
            }
        );
        const styles = {
        		css1: {
            		color: 'red'
            },
            css2: {
            		color: '#0f0'
            }
        }
      	return(
            <div>
                children = {children}
                <hr />
                <div>
                    BAD: <br />
                    {/* this.props = {this.props} */}
                    <div style={styles.css1}>
                        this.props.children = {this.props.color}
                    </div>
                    {/* this.props.arr = {this.props.arr} */}
                    {/* this.props.obj = {this.props.obj} */}
                    <br />
                    <p style={styles.css2}>
                        Object Error, need using map items to item
                    </p>
                </div>
            </div>
        );
    }
}

// text={message.text} => message object
class Message extends React.Component {
    render() {
    		//console.log(`this.props.text = `, this.props.text);
        //console.log(`this.props.key= `, this.props.key);
        let style = `
        		color: red;
            font-size: 23px;
        `;
        if(this.props.key === undefined){
        		//alert(`smg!`);
            console.log(`%c this.props.key= \n`, style, this.props.key);
        }
        return (
            <div>
                <hr />
                this.props.key = {this.props.key}
                <br />
                this.props.indexkey = {this.props.indexkey}
                <br />
                this.props.text = {this.props.text}
                <br />
                this.props.color = <span style={{backgroundColor: this.props.color}}>{this.props.color}</span>
                <br />
                <Button color={this.props.color} xyzClick={this.props.xyzClick}>
                    <span style={{color: '#fff'}}>Delete</span>
                </Button>
            </div>
        );
    }
}

// props.children === <span style={{color: '#fff'}}>Delete</span> ??? 
class Button extends React.Component {
    render() {
        return (
            <button
                style={{background: this.props.color}} 
                onClick={(e) => this.props.xyzClick(e)} 
                >
                {this.props.children}
            </button>
        );
    }
}




const text = [
    {
    text: "text 1",
    color: "red"
    },
    {
    text: "text 2",
    color: "blue"
    },
    {
    text: "text 3",
    color: "grey"
    },
    {
    text: "text 4",
    color: "green"
    },
    {
    text: "text 5",
    color: "#f0f"
    }
];
const color = "green";
const ArrayTest = [1, 2, 3];
const ObjectTest = {"key": "value"};

class App extends React.Component{
    constructor(props){
        super(props);
        this.state  = {
            showSate: false
        };
    }
    setModalVisible = (value) => {
        console.log(`showSate`, this.state.showSate);
        console.log(`value`, value);
        this.setState({
            showSate: value
        });
        // 状态更新可能是异步的
        setTimeout(() => {
        		console.log(`showSate`, this.state.showSate);
        });
    };
  	XC = (e) => {
      	let m = e.toString();
      	console.log(e, m);
      	return alert(`e.toString(); =\n`, m);
  	};
  render(){
      return(
          <div>
               <div>
                   <button onClick={() => console.log(`smg`)}>
                       onClick
                   </button>
                   <button onClick={()=>this.setModalVisible(true)}>
                       showModal{this.state.showSate}
                   </button>
               </div>
               <MessageList
                   messages={text}
                   color={color}
                   arr={ArrayTest}
                   obj={ObjectTest}
                   xyzClick={this.XC}/>
          </div>
      );
    }
};



export default App;

ReactDOM.render(
    <App />,
    mountNode
);

本文标签: javascripthow to get the 39ekey39 of li element in reactjsStack Overflow