Javascript 使用重复的组件解决组件状态问题

Javascript 使用重复的组件解决组件状态问题,javascript,reactjs,Javascript,Reactjs,我最近开始学习React,我有点困惑 请参阅以下内容或下面的代码片段 class App extends React.Component { constructor(props) { super(props); this.state = { sessions: [], sessionSelected: null } this.addSession = this.addSession.bind(this); this.switc

我最近开始学习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')
);
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
会议:[],
sessionSelected:null
}
this.addSession=this.addSession.bind(this);
this.switchSession=this.switchSession.bind(this);
}
addSession(){
让sessions=this.state.sessions;
let id=(sessions.length)
让title=“Session”+id;
让会话=;
会话。推送(会话);
这是我的国家({
会议:会议,
所选会议:id
});
}
交换会话(id){
这是我的国家({
所选会议:id
});
}
render(){
返回(
+添加会话
{this.state.sessions[this.state.sessionSelected]}
{this.state.sessions.map((x,i)=>{
返回{this.switchSession(i)}}/>;
})}
);
}
}
类会话扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
计数:0
}
this.startTimer=this.startTimer.bind(this);
this.count=this.count.bind(this);
}
startTimer(){
setInterval(这个.count,1000);
}
计数(){
这是我的国家({
计数:this.state.count+1
});
}
render(){
返回(
{this.props.title}
{this.state.count}

启动计时器 ) } } 类SessionSwitcher扩展React.Component{ render(){ 返回( {this.props.index} ) } } ReactDOM.render( , document.querySelector(“#app”) );
我希望能够在多个组件中触发多个计时器

出于某种原因,当我在一个组件中单击启动计时器时,它也会触发其他组件的启动计时器


有人能给我解释一下我做错了什么吗?

以下是一些你可以改变的事情,以获得更可预测的体验:

  • 与其将JSX存储在状态中(这是一个复杂的对象),不如只存储id,然后根据该id呈现JSX

  • 尽量不要原地改变状态(如将
    推送到已处于状态的数组上)

  • 如果您想在组件之间拥有持久计时器,无论当前选择了哪些,请确保在取消选择时不要卸载它们


  • 这里是您的

    的相关更新部分,非常感谢@glortho。很好用!
      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>
        );
      }