reactjs数组映射方法

reactjs array map method

我正在尝试在数组映射方法中添加视图更多或视图更少的部分,但是当我在映射方法内的按钮上使用 onclick 方法时,所有按钮都在起作用,而不是特定的按钮。

class Projects extends Component{
constructor(props){
super(props);
this.state={
  projects:[
    {
      id:1,
      title:'Calculator',
      description:'A Simple Javascript Calculator application'
    },
    {
      id:2,
      title:'ColorGuess',
      description:'A Javascript application'
    },
    {
      id:3,
      title:'GamesDB',
      description:'A React application',
    },
  ],
  clicked:false
  }
   this.toggle = this.toggle.bind(this)
 }

 toggle(){
  this.setState( state => ({
  clicked:!state.clicked
  }));
 }
render(){
  return(
   <div>
    <h2>My Projects</h2>
    <div className="d-flex flex-wrap justify-content-center">
    {
      this.state.projects.map( (project, i) =>{
        return(
          <div key={i} style={{width:'40%'}}>
            <div className="card">
              {project.title}
              <hr/>
              Description : {project.description} <br/>
              <button onClick={this.toggle}>
              {this.state.clicked ? <i class="fas fa-chevron-down"></i> : <i class="fas fa-chevron-up"></i>}
              </button>
            </div>
          </div>
        );
      })
     }
    </div>
   </div>
  );
 }
}

当我在渲染后单击单个按钮时,但所有其他按钮都起作用,而不是特定按钮。

我已经使用了箭头函数并且还传递了索引,但仍然无法正常工作,不确定哪里出错了。

嗯,所以你对所有组件使用一个状态,每次你设置一个状态时,它都会指向 clicked,它正在 this.state.clicked ? 中使用 要解决此问题,您必须为每个按钮维护单独的状态。

要解决此问题,您需要执行以下操作

class Projects extends Component{
constructor(props){
super(props);
this.state={
  projects:[
    {
      id:1,
      title:'Calculator',
      description:'A Simple Javascript Calculator application'
    },
    {
      id:2,
      title:'ColorGuess',
      description:'A Javascript application'
    },
    {
      id:3,
      title:'GamesDB',
      description:'A React application',
    },
  ],
  clicked:false
  }
   this.toggle = this.toggle.bind(this)
 }

 toggle = (index) => {
   const { projects } = this.state;
   const update = projects.map((item, key) => {
    return index === key ? {
      ...item,
      clicked: !item.clicked
    } : {
      ...item,
    };
  });
  this.setState({
    projects: update
  });
 }
render(){
  const { projects } = this.state;
  const renderButtons = projects.map( (project, i) => {
    return(
      <div key={i} style={{width:'40%'}}>
        <div className="card">
          {project.title}
          <hr/>
          Description : {project.description} <br/>
          <button onClick={(i) => this.toggle(i)}>
          {project.clicked ? <i class="fas fa-chevron-down"></i> : <i class="fas fa-chevron-up"></i>}
          </button>
        </div>
      </div>
    );
  })
  return(
   <div>
    <h2>My Projects</h2>
    <div className="d-flex flex-wrap justify-content-center">
    {renderButtons}
    </div>
   </div>
  );
 }
}

不是存储被点击的布尔值,而是存储被点击项目的 ID 并使用它来切换按钮的状态,例如

class Projects extends React.Component{
  constructor(props){
    super(props);
      this.state={
        projects:[
          {
            id:1,
            title:'Calculator',
            description:'A Simple Javascript Calculator application'
          },
          {
            id:2,
            title:'ColorGuess',
            description:'A Javascript application'
          },
          {
            id:3,
            title:'GamesDB',
            description:'A React application',
          },
        ],
        clicked:false
      }
     this.toggle = this.toggle.bind(this)
   }

   toggle(id){
    this.setState( state => ({
      clicked: id === state.clicked? null: id
    }));
   }
   
   render(){
      return(
       <div>
        <h2>My Projects</h2>
        <div className="d-flex flex-wrap justify-content-center">
        {
          this.state.projects.map( (project, i) =>{
            return(
              <div key={i} style={{width:'40%'}}>
                <div className="card">
                  {project.title}
                  <hr/>
                  Description : {project.description} <br/>
                  <button type="button" onClick={() => this.toggle(project.id)}>
                  {this.state.clicked === project.id ? 'up' : 'down'}
                  </button>
                </div>
              </div>
            );
          })
         }
        </div>
       </div>
      );
    }
}

ReactDOM.render(<Projects />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.1/umd/react-dom.production.min.js"></script>
<div id="root" />