简体   繁体   English

在ReactJS中在onClick时添加道具

[英]Add prop when onClick in ReactJS

I would like to change current li item color when I click it. 单击后,我想更改当前li项目的颜色。

How to add prop to item(using array map), when I click it? 当我单击道具时如何向道具添加道具(使用数组映射)? I use styled-components 我使用样式组件

const Li = styled.li`
  color: ${props => (props.checked ? "red" : "green")};
`;

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: "",
      items: []
    };
  }

  render() {
    const ShowItems = this.state.items.map((item, index) => {
      return (
        <Li key={index}>
          {item}
          <button onClick={() => this.deleteItemHandler(index)}> Delete</button>
        </Li>
      );
    });

    return (
      <Wrapper>
        <AddItem
          addItemHandler={this.addItem}
          InputValue={this.state.value}
          InputValueHandler={this.inputValue}
        />
        {ShowItems}
      </Wrapper>
    );
  }
}

So you need keep track of the active index, and use it too change the color of the active component color. 因此,您需要跟踪活动索引,并使用它来更改活动组件颜色的颜色。

state ={
 activeIndex: void 0 
}

const Li = styled.li`
   color: ${props => props.checked ? "red" : "green"};
   ;`

deleteItemHandler = (index) => {
  this.setState({
   activeIndex: index
  })
}


render() {
    const ShowItems = this.state.items.map((item, index) => {
      return (
        <Li key={index} checked={index === this.state.activeIndex} > {item} < button onClick={() => this.deleteItemHandler(index)
        }> Delete</button ></Li >
      )
    })

    return (
      <Wrapper>
        <AddItem
          addItemHandler={this.addItem}
          InputValue={this.state.value}
          InputValueHandler={this.inputValue}
        />
        {ShowItems}
      </Wrapper>
    );

Try this 尝试这个

     const Li = styled.li`
       color: ${props => props.checked ? "red" : "green"};
       ;`

    class App extends Component {
      constructor(props) {
        super(props);
        this.state = {
          value: "",
          items: [],
          currentChecked: null
        };
      }

     render() {
        const ShowItems = this.state.items.map((item, index) => {
          return (
            <Li key={index} checked={index === this.state.currentChecked} >
              {item} 
              <button onClick={() => this.setState({currentChecked: index})}>Delete</button >
            </Li >
           )
        })

        return (
          <Wrapper>
            <AddItem
              addItemHandler={this.addItem}
              InputValue={this.state.value}
              InputValueHandler={this.inputValue}
            />
            {ShowItems}
          </Wrapper>
        );

Check out this code working on CodeSandBox 看看在CodeSandBox上工作的这段代码

import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
import styled from "styled-components";

const Li = styled.li`
  color: ${props => (props.checked ? "red" : "green")};
`;

class App extends Component {
  state = {
    value: "",
    items: [],
    selected: -1
  };

  handleChange = e => {
    this.setState({
      [e.currentTarget.name]: e.currentTarget.value
    });
  };

  handleAdd = () => {
    const { items, value } = this.state;
    this.setState({
      items: [...items, value],
      value: ""
    });
  };

  handleRemove = index => {
    const { items, selected } = this.state;
    items.splice(index, 1);
    if (index < selected) index = selected - 1;
    if (index === selected) index = -1;
    if (index > selected) index = selected;
    this.setState({
      items: items,
      selected: index
    });
  };

  handleActiveItem = index => {
    this.setState({ selected: index });
  };

  render() {
    const { value, items, selected } = this.state;
    return (
      <div>
        <input
          type="text"
          value={value}
          name="value"
          onChange={this.handleChange}
        />
        <button
          style={{ margin: "0px 5px" }}
          disabled={!value}
          className="btn btn-sm btn-success"
          onClick={this.handleAdd}
        >
          +
        </button>
        <ul className="li">
          {items.map((item, index) => (
            <Li key={index} checked={selected === index}>
              <span onClick={() => this.handleActiveItem(index)}>{item}</span>
              <button
                style={{ margin: "1px 5px" }}
                className="btn btn-sm btn-danger"
                onClick={() => this.handleRemove(index)}
              >
                X
              </button>
            </Li>
          ))}
        </ul>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Ignore the handlers if you don't need them. 如果不需要处理程序,请忽略它们。 Thanks to this effort I learnt about styled-components and discovered CodeSandBox. 由于这项工作,我了解了styled-components并发现了CodeSandBox。

EDIT : 编辑:

  • Added a <span> inside <li> to avoid nested onClick , previously <li> (parent) and <button> (child) both had onClick attribute. <span> inside <li>添加了<span> inside <li>以避免嵌套onClick ,以前的<li> (父级)和<button> (子级)都具有onClick属性。 On button Click two onClick events were fired resulting in unexpected behaviour in some use cases. “单击按钮”触发了两个onClick事件,在某些用例中导致意外行为。 You must correct this in your code . 您必须在代码中更正此错误
  • Added logic to keep item selected when an item before it is deleted. 添加了逻辑,可以在删除项目之前使项目保持选中状态。
  • Added button validation to avoid adding empty string/items in list. 添加了按钮验证,以避免在列表中添加空字符串/项目。
  • Also updated CodeSandBox Code to reflect above changes. 还更新了CodeSandBox代码以反映上述更改。

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

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