首页 > 解决方案 > 如何在 react.js 中更改单个组件 onClick 的样式

问题描述

我尝试在反应中建立一个待办事项列表。

到目前为止,我有 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 事件处理程序。

无论如何,每次我发布新条目时,ref 似乎都会被覆盖......

现在,总是处理所有条目中的最后一个。我怎样才能正确处理每个条目?解决此类问题的最佳做法是什么?

标签: javascriptreactjs

解决方案


您可以将带有待办事项索引/键的附加道具传递到待办事项列表的每个项目中。通过将事件对象传递给您的处理程序 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>
  )
}

推荐阅读