从类方法引用react组件

时间:2018-03-16 01:10:06

标签: reactjs dom

我有一个动态待办事项列表我想添加一个"突出显示"功能。每个列表项都会显示突出显示的标记,该标记仅应显示已单击的列表项。

export class Todo extends Component {

constructor(props) {
  super(props);
  this.state = {input: '', todos: this.getOldTodo()};
  this.selectItem = this.selectItem.bind(this);
}

  //shortened

  selectItem(i) {
    this.setState({selected: i});
    if (this.state.selected == i) {
    // --- this is the code that needs to change the right list items child's class  
      ???.props.childen[2].className = "active";
    // ---
      console.log("true")
    }
    console.log(i);

  }

  render() {
            //markup also shortened 
            this.state.todos.map((todos, i) => {
              return (
                                                                   //What do I pass to the method here?
                <li key={todos.key} className="todo-li-item" onClick={this.selectItem.bind(this, i)}>
                  <span className="todo-item">{todos.text}</span>
                  <span onClick={this.deleteItem.bind(this, i)} className="delet-todo">&#10005;</span>

                  // --- This is the child that needs its class changed when it's parent is clicked 

                  <div id="todo-select" className={"hidden"}>
                    <span id="todo-select-top"></span>
                    <span id="todo-select-left"></span>
                  </div>  
                </li>
              );
            })
        </ul>
      </div>
    );
  }
}

这很简单,但是我用来做这件事的反应非常明显,但是嘿,我还在学习。谢谢你的时间。

2 个答案:

答案 0 :(得分:1)

你已经非常接近了。这是我的实施。 关键点:不要改变状态对象。

selectItem(idx) {
  this.setState(state => {
    const todos = [
      state.todos.slice(0, idx),
      { ...state.todos[idx], selected: ! state.todos[idx].selected },
      state.todos.slice(idx + 1, state.todos.length),
    ]
    return {
      ...state,
      todos,
    }
  })
}

deleteItem(idx) {
  this.setState(state => {
    const todos = [...state.todos]
    todos.splice(idx, 1)
    return {
      ...state,
      todos,
    }
  })
}

render() {
  return (
    <div>
      <ul>
        {this.state.todos.map((todo, idx) => (
          <li
            key={todo.key}
            className={'todo-li-item'}
            onClick={this.selectItem.bind(this, idx)}
          >
            <span className="todo-item">{todo.text}</span>
            <span
              onClick={this.deleteItem.bind(this, idx)}
              className="delete-todo"
            >
              &#10005;
            </span>
            <div id="todo-select" className={todo.selected && 'active'}>
              <span id="todo-select-top" />
              <span id="todo-select-left" />
            </div>
          </li>
        ))}
      </ul>
    </div>
  )
}

答案 1 :(得分:1)

  • 列表项可以是无状态组件,因此onSelectonDelete成为回调函数。

  • 删除带索引的项目可能会让您遇到麻烦,因为每次React都不会重新呈现整个列表。

  • 我不知道getOldTodo内有什么,但custructor不能等。因此,如果它是异步函数,它最初将为null。

有一种使用ES6语法的实现 每个列表项都是无状态的:

const ListItem = props => {
  const { todo, deleteItem, selectItem } = props;
  return (
    <li key={todo.key} className="todo-li-item" onClick={selectItem}>
      <span className="todo-item">{todos.text}</span>
      <span onClick={deleteItem} className="delet-todo">
        &#10005;
      </span>
      clicked
      <div id="todo-select" className={'hidden'}>
        <span id="todo-select-top" />
        <span id="todo-select-left" />
      </div>
    </li>
  );
};

所有事件都由有状态组件处理:

export class Todo extends Component {
  state = {
    input: '',
    todos: [],
  };

  async componentDidMount() {
    const todos = await this.getOldTodo();
    this.setState({ todos });
  }

  render() {
    return (
      <div>
        {this.state.todos.map(todo => (
          <ListItem
            todo={todo}
            key={todo.key}
            selectItem={() => {
              this.selectItem(todo);
            }}
            deleteItem={() => {
              this.deleteItem(todo);
            }}
          />
        ))}
      </div>
    );
  }

  selectItem = todo => {
    const idx = this.state.todos.findIndex(i => i.key === todo.key);
    const todos = this.state.todos.slice();
    const todo = { ...this.state.todos[idx] };
    // change
    todos[idx] = todo;
    this.setState({
      todos
    });
  }

  deleteItem = todo => {
    const idx = this.state.todos.findIndex(i => i.key === todo.key);
    const todos = this.state.todos.splice(idx, 1);
    this.setState({
      todos
    });
  }

  getOldTodo = async () => {
    //...
  }
}

这对你有意义吗?