我有 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
[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/