繁体   English   中英

如何在react.js中更改单个组件onClick的样式

[英]How to change style of single component onClick in react.js

我试着建立一个待办事项清单。

到目前为止,我有2个组件:

第一个处理输入:

import React from 'react';
import ListItems from './ListItems.js';

class InputComponent extends React.Component {
    constructor(){
        super();

        this.state = {
            entries: []
        }

        this.getText = this.getText.bind(this);
    }

    getText() {
        if(this._inputField.value !== '') {
            let newItem = {
                text: this._inputField.value,
                index: Date.now()
            }

            this.setState((prevState) => {
                return {
                    entries: prevState.entries.concat(newItem)
                }
            })
            this._inputField.value = '';
            this._inputField.focus();

        }
    }

    render() {
        return(
            <div>
                <input ref={ (r) => this._inputField = r } >
                </input>
                <button onClick={ () => this.getText() }>Go</button>
                <div>
                    <ListItems 
                        entries={this.state.entries}   
                    />
                </div>
            </div>
        )
    }   
}

export default InputComponent;

第二个是关于列表中的实际条目:

import React from 'react';

class ListItems extends React.Component {

    constructor() {
        super();

        this.lineThrough = this.lineThrough.bind(this);
        this.listTasks = this.listTasks.bind(this);
    }

    lineThrough(item) {
        console.log(item);
        //item.style = {
        //    textDecoration: 'line-through'
        //}
    }

    listTasks(item) {
        return(
            <li key = { item.index }>
                <div 
                    ref = { (r) => this._itemText = r } 
                    style = {{
                        width: 50 + '%',
                        display: 'inline-block',
                        backgroundColor: 'teal',
                        color: 'white',
                        padding: 10 + 'px',
                        margin: 5 + 'px',
                        borderRadius: 5 + 'px'
                    }}
                >
                    { item.text }
                </div>
                <button onClick={ () => this.lineThrough(this._itemText) }>Done!</button>
                <button>Dismiss!</button>
            </li>
        )
    }

    render() {
        let items = this.props.entries;
        let listThem = items.map( this.listTasks );

        return(
            <ul style = {{
                listStyle: 'none'
            }}>
            <div>
                { listThem }
            </div>
            </ul>
        )
    }
}

export default ListItems;

如您所见,我要为每个条目有两个按钮,一个要使文本成为直行,一个要删除该条目。

我目前停留在尝试用“完成!”解决特定条目的问题上。 按钮以使该条目的文本直行。

我在包含要设置样式的文本的div上设置了一个引用,并将该引用传递给onClick事件处理程序。

无论如何,每次我发布新条目时,引用似乎都被覆盖了。

现在,总是解决所有条目中的最后一个条目。 如何正确处理每个条目? 解决此类问题的最佳实践是什么?

您可以将带有待办事项索引/关键字的其他道具传递到待办事项列表的每个项目中。 通过将事件对象传递给处理程序lineThrough(),您现在可以从事件目标的属性中获取相关的todo id。

亲切的问候

class TodoList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      todos: []
    }
    this.done = this.done.bind(this);
  }

  done(id) {
    this.state.todos[id].done();
  }

  render() {
    return (
      this.state.todos.map(t => <Todo item={t} onDone={this.done} />)
    );
  }
}

const Todo = ({item, onDone}) => {
  return (
    <div>
      <h1>{item.title}</h1>
      <button onClick={() => onDone(item.id)}>done</button>
    </div>
  )
}

您需要映射listItems,然后每个列表项都有自己的引用

import React from 'react';
import ReactDOM from 'react-dom';
class ListItems extends React.Component {

    constructor() {
        super();

        this.lineThrough = this.lineThrough.bind(this);
    }

    lineThrough(item) {
        item.style.textDecoration = "line-through";
    }
    render() {

        return(
            <ul style = {{
                listStyle: 'none'
            }}>
            <div>
                    <li key={this.props.item.index}>
                        <div
                            ref={(r) => this._itemText = r}
                            style={{
                                width: 50 + '%',
                                display: 'inline-block',
                                backgroundColor: 'teal',
                                color: 'white',
                                padding: 10 + 'px',
                                margin: 5 + 'px',
                                borderRadius: 5 + 'px'
                            }}
                        >
                            {this.props.item.text}
                        </div>
                        <button onClick={() => this.lineThrough(this._itemText)}>Done!</button>
                        <button>Dismiss!</button>
                    </li>
            </div>
            </ul>
        )
    }
}

class InputComponent extends React.Component {
    constructor(){
        super();

        this.state = {
            entries: []
        }

        this.getText = this.getText.bind(this);
    }

    getText() {
        if(this._inputField.value !== '') {
            let newItem = {
                text: this._inputField.value,
                index: Date.now()
            }

            this.setState((prevState) => {
                return {
                    entries: prevState.entries.concat(newItem)
                }
            })
            this._inputField.value = '';
            this._inputField.focus();

        }
    }

    render() {
        return(
            <div>
                <input ref={ (r) => this._inputField = r } >
                </input>
                <button onClick={ () => this.getText() }>Go</button>
                <div>
                    {this.state.entries.map((item, index) => {
                        return <ListItems key={index} item={item} />
                    })}
                </div>
            </div>
        )
    }   
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM