reactjs数组映射方法

时间:2019-02-14 07:01:38

标签: reactjs es6-map

我试图在数组map方法中增加一个视图或减少一个视图部分,但是当我在map方法内的一个按钮上使用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>
  );
 }
}

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

我已经使用了箭头功能,并且还与索引一起传递了索引,但仍然无法正常工作,不确定它出了错。

2 个答案:

答案 0 :(得分:1)

存储点击项目的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" />

答案 1 :(得分:0)

嗯,所以您对所有组件都使用一种状态,每次设置状态时,它都将寻址到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>
  );
 }
}