反应:如何映射对象数组,然后onclick将一个状态单独添加到另一个数组中?

时间:2018-09-17 22:18:20

标签: javascript reactjs

我不知道如何使用元素的键分别添加到新数组。我在这里使用新数组onclick的函数设置了状态:

this.state = {
  applications: [
    {
      id: 1,
      name: "John Smith",
      position: "Server",
      applied: "03/15/16",
      experience: 2,
      availability: {
        M: 2,
        T: 2,
        W: 1,
        Th: 2,
        F: 1,
        S: 0,
        Su: 0
      },
      questions: [
        {
          text: "Have you ever been convicted of a felony?",
          answer: "No"
        }
      ]
    },
    {
      id: 2,
      name: "Jane Smith",
      position: "Cook",
      applied: "02/08/16",
      experience: 4,
      availability: {
        M: 1,
        T: 1,
        W: 1,
        Th: 1,
        F: 0,
        S: 0,
        Su: 0
      },
      questions: [
        {
          text: "Have you ever been convicted of a felony?",
          answer: "Yes"
        }
      ]
    },
    {
      id: 3,
      name: "David Jessup",
      position: "Chef",
      applied: "03/08/16",
      experience: 2,
      availability: {
        M: 2,
        T: 2,
        W: 2,
        Th: 2,
        F: 2,
        S: 0,
        Su: 0
      },
      questions: [
        {
          text: "Are you authorized to work in the United States?",
          answer: "Yes"
        }
      ]
    },
    {
      id: 4,
      name: "Clay vanSchalkwijk",
      position: "Cook",
      applied: "03/08/16",
      experience: 1,
      availability: {
        M: 1,
        T: 0,
        W: 1,
        Th: 0,
        F: 1,
        S: 0,
        Su: 0
      },
      questions: [
        {
          text: "Are you authorized to work in the United States?",
          answer: "Yes"
        }
      ]
    }
  ],
  saved: []
};

这是我要运行的功能:

onFavorite = savedApp =>
  this.setState({
    saved: [...this.state.saved, savedApp]
  });

在这里我要单击“收藏夹”,然后让它运行该函数并添加到新数组(通过键ID):

render() {
  const all_applications = this.state.applications.map(function(elem) {
    return (
      <li key={elem.id}>
        {" "}
        <h1>{elem.name}</h1>
        <p />
      </li>
    );
  });
  return (
    <div className="App">
      <Header />
      {all_applications}
      <button onClick={this.onFavorite}>Favorite</button>
    </div>
  );
}

2 个答案:

答案 0 :(得分:0)

如果我正确理解了您的问题,则可以通过对render()函数进行以下调整,为每个申请人提供一个“收藏夹”按钮:

render() {
    const all_applications = this.state.applications.map((elem) => {
      return(
        <li key={elem.id}> <h1>{elem.name}</h1>
          <p></p>
          { /* Render a favourite button for each 'elem' applicant. 
               Pass the elem/applicant data to the onFavorite method like so:
            */  }
          <button onClick={ () => this.onFavorite(elem) }>Favorite</button>
        </li>
      )
    })
    return (
      <div className="App">
      <Header />
      {all_applications}
      </div>
    );
  }
}

答案 1 :(得分:0)

这是一个略有不同的方法,具有单独的Application组件。 onFavorite方法仅将id添加到saved状态。如果id已经存在,则将其删除。 renderFavs方法映射saved状态,然后从该状态中获取相关的应用程序。

class App extends React.Component {
  state = {
    applications: [
      {
        id: 1,
        name: "John Smith",
        position: "Server",
        applied: "03/15/16",
        experience: 2,
        availability: {
          M: 2,
          T: 2,
          W: 1,
          Th: 2,
          F: 1,
          S: 0,
          Su: 0
        },
        questions: [
          {
            text: "Have you ever been convicted of a felony?",
            answer: "No"
          }
        ]
      },
      {
        id: 2,
        name: "Jane Smith",
        position: "Cook",
        applied: "02/08/16",
        experience: 4,
        availability: {
          M: 1,
          T: 1,
          W: 1,
          Th: 1,
          F: 0,
          S: 0,
          Su: 0
        },
        questions: [
          {
            text: "Have you ever been convicted of a felony?",
            answer: "Yes"
          }
        ]
      },
      {
        id: 3,
        name: "David Jessup",
        position: "Chef",
        applied: "03/08/16",
        experience: 2,
        availability: {
          M: 2,
          T: 2,
          W: 2,
          Th: 2,
          F: 2,
          S: 0,
          Su: 0
        },
        questions: [
          {
            text: "Are you authorized to work in the United States?",
            answer: "Yes"
          }
        ]
      },
      {
        id: 4,
        name: "Clay vanSchalkwijk",
        position: "Cook",
        applied: "03/08/16",
        experience: 1,
        availability: {
          M: 1,
          T: 0,
          W: 1,
          Th: 0,
          F: 1,
          S: 0,
          Su: 0
        },
        questions: [
          {
            text: "Are you authorized to work in the United States?",
            answer: "Yes"
          }
        ]
      }
    ],
    saved: []
  };

  onFavorite = app => {
    const { saved } = this.state;
    const check = saved.includes(app.id);
    if (check) {
      const newSaved = saved.filter(fav => fav !== app.id);
      return this.setState({ saved: newSaved });
    }
    this.setState(currentState => ({
      saved: [...currentState.saved, app.id]
    }));
  };

  renderApplications() {
    const { applications } = this.state;
    return applications.map(app => (
      <Application key={app.id} app={app} onFavorite={this.onFavorite} />
    ));
  }

  renderFavs() {
    const { saved, applications } = this.state;
    const saveds = saved.map(id => applications.find(app => app.id === id));
    return saveds.map(fav => <p key={fav.id}>{fav.name}</p>);
  }

  render() {
    return (
      <div>
        <ul>{this.renderApplications()}</ul>
        <h3>Favorites</h3>
        {this.renderFavs()}
      </div>
    );
  }
}

const Application = props => {
  const { app, onFavorite } = props;
  const handleFavorite = () => onFavorite(app);

  return <li onClick={handleFavorite}>{app.name}</li>;
};

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