私は最近Reactを学び始めましたが、少し混乱しています。
次のコードペンまたは以下のコードスニペットを参照してください。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
sessions: [],
sessionSelected: null
}
this.addSession = this.addSession.bind(this);
this.switchSession = this.switchSession.bind(this);
}
addSession() {
let sessions = this.state.sessions;
let id = (sessions.length)
let title = "Session " + id;
let session = <Session title={title} index={id + 1} />;
sessions.push(session);
this.setState({
sessions: sessions,
sessionSelected: id
});
}
switchSession(id) {
this.setState({
sessionSelected: id
});
}
render() {
return (
<div>
<button onClick={this.addSession} >+ Add Session</button>
<div>{this.state.sessions[this.state.sessionSelected]}</div>
<div className="switchers">
{this.state.sessions.map((x, i) => {
return <SessionSwitcher index={i + 1} onClick={() => { this.switchSession(i) }} />;
})}
</div>
</div>
);
}
}
class Session extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
this.startTimer = this.startTimer.bind(this);
this.count = this.count.bind(this);
}
startTimer() {
setInterval(this.count, 1000);
}
count() {
this.setState({
count: this.state.count + 1
});
}
render() {
return (
<div>
<h1>{this.props.title}</h1>
<p>{this.state.count}</p>
<button onClick={this.startTimer}>Start Timer</button>
</div>
)
}
}
class SessionSwitcher extends React.Component {
render() {
return (
<div className="switcher" onClick={this.props.onClick}>
<span>{this.props.index}</span>
</div>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#app')
);
複数のコンポーネント内で複数のタイマーをトリガーできるようにしたい。
何らかの理由で、1つのコンポーネントで開始タイマーをクリックすると、他のコンポーネントでも開始タイマーがトリガーされます。
誰かが私が間違っていることを私に説明できますか?
より予測可能なエクスペリエンスを得るために変更できることがいくつかあります。
複雑なオブジェクトである状態でJSXを格納するのではなく、IDのみを格納し、そのIDに従ってJSXをレンダリングします。
状態をその場で変更しないようにしてください(push
すでに状態になっている配列へのingの場合のように)。
現在選択されているタイマーに関係なく、コンポーネント間で永続的なタイマーを設定する場合は、選択が解除されたときにそれらをアンマウントしないようにしてください。
<App/>
コンポーネントの関連する更新された部分は次のとおりです(これらはベストプラクティスよりも迅速な修正であることに注意してください)。
addSession() {
const id = this.state.sessions.length;
this.setState( state => ({
// treat your state as immutable
sessions: state.sessions.concat( id ),
sessionSelected: id
}));
}
// don't unmount when switching components, just hide
render() {
return (
<div>
<button onClick={this.addSession} >+ Add Session</button>
<div>
{ this.state.sessions.map( session =>
<div style={{ display: session === this.state.sessionSelected ? 'block' : 'none' }}>
<Session title={"Session " + session} />
</div>
)}
</div>
<div className="switchers">
{this.state.sessions.map((x, i) => {
return <SessionSwitcher index={i + 1} onClick={() => { this.switchSession(i) }} />;
})}
</div>
</div>
);
}
ここで試してみてください:https://codepen.io/glortho/pen/ZrLMda?editors = 0011
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加