javascript - 使用 key 唯一标识每个元素并将 props 更改为 ReactJS 中的该元素

标签 javascript reactjs

我有 JSON 数组中的 JSON 对象列表。其中每个元素都用 key 唯一标识

JSON 对象包含:

event_name

date_time

{this.props.events.map((event) =>
   (
    <div key={event.event_name}>
        <ul>
          <div><h4>{event.event_name}</h4>
            <div>            //ternary operation next line
            {this.state.mic?<span onClick={()=>this.onMicClickOn(event.event_name)}>
           <MicOn /> </span> :<span onClick={()=>this.onMicClickOff(event.event_name)}>
           <MicOff /> </span>}              
                 </div>
                 </div>
                 <li>{event.date_time}</li></ul>
               </div>
            ))}

我有这个状态

constructor(props) {
        super(props);
        this.state = {
          mic : false,
        }

      }

onMicClickOff=event =>{
        this.setState({ mic: true });
    }

onMicClickOn =event =>{
    this.setState({ mic : false});
}

我只想仅在特定于 event.event_name 时显示麦克风的关闭和打开情况。 目前发生的情况是我在 JSON 对象的每个事件上显示麦克风打开和麦克风关闭,而不是单击的对象。而只是唯一 key

我知道麦克风状态是全局声明并为所有人声明的问题。但是我可以做些什么来将 event_name 附加到麦克风状态以使其独一无二。

最佳答案

您可以使用状态属性来保持每个单独的事件的开/关位置,而不是保持通用的位置。

class App extends React.Component {
  state = {
    micStates: {}
  };

  handleMicState = id =>
    this.setState(current => ({
      micStates: { ...current.micStates, [id]: !current.micStates[id] }
    }));

  render() {
    return (
      <div>
        {this.props.events.map(event => (
          <div key={event.event_name}>
            <ul>
              <div>
                <h4>{event.event_name}</h4>
                <div>
                  {this.state.micStates[event.id] ? (
                    <span onClick={() => this.handleMicState(event.id)}>
                      <p>On</p>{" "}
                    </span>
                  ) : (
                    <span onClick={() => this.handleMicState(event.id)}>
                      <p>Off</p>{" "}
                    </span>
                  )}
                </div>
              </div>
              <li>{event.date_time}</li>
            </ul>
          </div>
        ))}
      </div>
    );
  }
}

const events = [
  { id: 1, event_name: "foo", date_time: 12345 },
  { id: 2, event_name: "bar", date_time: 67890 },
  { id: 3, event_name: "baz", date_time: 12345 }
];
ReactDOM.render(<App events={events} />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

关键部分在这里:

handleMicState = id =>
    this.setState(current => ({
      micStates: { ...current.micStates, [id]: !current.micStates[id] }
}));

这里发生了两件事。

首先,我们使用 setState 函数而不是直接使用对象。这是因为我们正在使用以前的状态属性来设置新状态。如果我们的新状态依赖于旧状态,这是执行 setState 的建议方法,因为 setState 是异步的。

其次,我们将 event id 更改为 false/true。在第一个渲染中,micStates 中没有任何内容,因此每个麦克风事件都关闭。第一次点击时,第一个事件的情况如下:

micStates: { 1: true }

等等...

micStates: { 1: true, 2: false, 3: true } // etc.

这是spread syntax .

...current.micStates

这是computed property names .

[id]: !current.micStates[id]

也许是一个更好的方法:

class App extends React.Component {
  state = {
    micStates: {}
  };

  handleMicState = id =>
    this.setState(current => ({
      micStates: { ...current.micStates, [id]: !current.micStates[id] }
    }));

  render() {
    return (
      <div>
        {this.props.events.map(event => (
          <Event
            micState={this.state.micStates[event.id]}
            event={event}
            onMicState={this.handleMicState}
          />
        ))}
      </div>
    );
  }
}

const Event = ({ event, onMicState, micState }) => {
  const handleClick = () => onMicState(event.id);
  return (
    <div key={event.event_name}>
      <ul>
        <div>
          <h4>{event.event_name}</h4>
          <div>
            {micState ? (
              <span onClick={handleClick}>
                <p>On</p>{" "}
              </span>
            ) : (
              <span onClick={handleClick}>
                <p>Off</p>{" "}
              </span>
            )}
          </div>
        </div>
        <li>{event.date_time}</li>
      </ul>
    </div>
  );
};

const events = [
  { id: 1, event_name: "foo", date_time: 12345 },
  { id: 2, event_name: "bar", date_time: 67890 },
  { id: 3, event_name: "baz", date_time: 12345 }
];
ReactDOM.render(<App events={events} />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

关于javascript - 使用 key 唯一标识每个元素并将 props 更改为 ReactJS 中的该元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53605920/

相关文章:

javascript - 如何管理不同按钮点击时的多个叠加层?

javascript - Font Awesome 5,如何设置svg伪元素的样式?

reactjs - 如何让Material-UI V5自动生成:hover colors in custom color objects for buttons

javascript - react 不渲染?

reactjs - 获取 : Could not detect any platform in the source directory. 以在 Azure 静态站点上部署 React

javascript - 如何优化字符串到 DOM 的转换?

javascript - 如何将 jquery 对象传递给 "On"方法(第二个参数)?

reactjs - 运行 npm install 时有关对等依赖项的警告

javascript - 更改 node_modules 中的包时如何触发 React 的热重载?

javascript - 无法使用 JavaScript 删除文本字段