Making two API calls in the same component - reactjs - javascript

I'm building an app that produces two tables, each with 5 results. I can't seem to figure out how to crack the code when it comes to mapping over the second table. Table one is {renderItems}, table two is {renderUsers}. The API call for each is at the top of the App.js file detailed below, as 'repoURL' and 'userURL' respectively.
import React, { Component } from 'react';
import axios from 'axios';
const repoURL = 'https://api.github.com/search/repositories?q=stars:>1&s=stars&type=Repositories&per_page=5';
const userURL = 'https://api.github.com/search/users?q=created:>=2016-05-29&type=Users&s=followers&per_page=5';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
items: []
}
}
componentDidMount() {
var _this = this;
axios.get(repoURL)
.then(function(res){
console.log(res)
_this.setState({
items: res.data.items
});
})
.catch(function(e) {
console.log('ERROR ', e);
})
axios.get(userURL)
.then(function(res){
console.log(res)
_this.setState({
users: res.data.items
});
})
.catch(function(e) {
console.log('ERROR ', e);
})
}
render() {
const renderItems = this.state.items.map(function(item, i) {
return (
<div key={i} className="row">
<div className="col-md-3">{item.id}</div>
<div className="col-md-3">{item.name}</div>
<div className="col-md-3">{item.description}</div>
<div className="col-md-3">{item.stargazers_count}</div>
</div>
);
});
console.log(renderItems)
const renderUsers = this.state.items.map(function(item, i) {
return (
<div key={i} className="row">
<div className="col-md-3">{item.id}</div>
<div className="col-md-3">{item.name}</div>
<div className="col-md-3">{item.description}</div>
<div className="col-md-3">{item.stargazers_count}</div>
</div>
);
});
console.log(renderUsers)
return (
<div className="App">
<div className="row">
<div className="col-md-6 ">
<button type="button" id="hot_repo" className="btn btn-lg btn-danger">Hot Repositories</button>
</div>
<div className="col-md-6 ">
<button type="button" id="prolific_users" className="btn btn-lg btn-success">Prolific Users</button>
</div>
<div id="repoTable" className="col-md-6 panel panel-default">
<div id="repoHeader" className="panel-heading">5 Most Starred Repositories Last Month</div>
<div className="repoSubHeader panel-body">
<div id="repoId" className="col-md-3">ID</div>
<div id="repoName" className="col-md-3">Name</div>
<div id="repoDescription" className="col-md-3">Description</div>
<div id="repoStars" className="col-md-3">Stars</div>
</div>
<div className="row">
{renderItems}
</div>
</div>
<div id="userTable" className="col-md-6 panel panel-default">
<div id="userHeader" className="panel-heading">5 Most Active Users</div>
<div className="userSubHeader panel-body">
<div id="userId" className="col-md-3">ID</div>
<div id="userLogin" className="col-md-3">Login</div>
<div id="userAvatar" className="col-md-3">Avatar</div>
<div id="userFollowers" className="col-md-3">Followers</div>
</div>
<div className="row">
{renderUsers}
</div>
</div>
</div>
</div>
);
}
}
I feel like I'm missing something obvious, but I've been looking at it so long it's not going to be obvious to me at this point. Any help appreciated.

You have to initialize your state in the constructor as:
this.state = {
users: [],
items: []
}
and then you have to map the state items as:
const renderItems = this.state.items.map(function(item, i) {
return (
<div key={i} className="row">
<div className="col-md-3">{item.id}</div>
<div className="col-md-3">{item.name}</div>
<div className="col-md-3">{item.description}</div>
<div className="col-md-3">{item.stargazers_count}</div>
</div>
);
});
const renderUsers = this.state.users.map(function(item, i) {
return (
<div key={i} className="row">
<div className="col-md-3">{item.id}</div>
<div className="col-md-3">{item.name}</div>
<div className="col-md-3">{item.description}</div>
<div className="col-md-3">{item.stargazers_count}</div>
</div>
);
});
console.log(renderUsers)
This is under the assumption that your userUrl returns:
{
items: [
user1,
user2,
...
]
}
If it doesn't, then you need to change this part accordingly.
axios.get(userURL)
.then(function(res){
console.log(res)
_this.setState({
users: res.data.items
});
})
.catch(function(e) {
console.log('ERROR ', e);
})

the first problem I think you are doing a map assigning to const renderUsers a wrong mapping this.state.items.
Secondly you need to declare users key in the this.state in the constructor.
this.setState({ users: [], items: [] })

Related

React: Update component data/props after promise resolved

I'm a bit new to React and I've been having some problems understanding the workarounds of certain methods that I've used in other languages.
The Problem:
What I was hoping to achieve is that whenever the user clicks a button, the app will render a new section displaying some variable values. What I did was that when the user clicked a button, an state changed, and let the new Component render, and I passed the data through its props.
The problem is, If I understand correctly, that I'm passing the old values when I create the component and not the actual/updated values that I want to render...
Let's say I have this following variables.
const user_data = {
pic_url: 'null',
followers: 'Loading...',
followings: 'Loading...',
nTweets: 'Loading...',
};
Those variables are going to change value whenever the user click a button.
This next block of code is what I use to render the next component where I want the new values.
const SomeComponent = props => {
const [resolved, setResolved] = useState({ display: false });
const displayValidation = props => {
setResolved({ ...resolved, display: !resolved.display });
};
function getData(username) {
const url = 'https://www.twitter.com/' + username;
getHTML(url)
.then(res => {
getUserData(res).then(res => {
user_data.followers = res.followers;
user_data.followings = res.followings;
user_data.nTweets = res.nTweets;
user_data.pic_url = res.pic_url;
console.log('Updated data:', user_data);
displayValidation();
});
})
.catch(function(error) {
console.error('Username was not found.');
});
}
const handleSubmit = event => {
event.preventDefault();
console.log('Resolving data...');
getData(user.username);
};
return (
<React.Fragment>
<Navbar />
<div className="container lg-padding">
<div className="row" id="getTracker">
<div className="col-sm-12 center">
<div className="card text-center hoverable">
<div className="card-body">
<div className="input-field">
<i className="material-icons prefix">account_circle</i>
<input
id="username"
type="text"
className="validate"
value={user.username}
onChange={handleChange}
/>
<label htmlFor="username">Enter a username to track</label>
</div>
<input
type="button"
onClick={handleSubmit}
value="Track"
className="btn-large blue darken-4 waves-effect waves-light"
/>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
**{resolved.display && <DisplayData type={1} data={user_data} />}**
</div>
</div>
</div>
<Footer />
</React.Fragment>
);
};
I want to see the new values, but it always render the first values that I passed when creating the component.
This is the component that I create
import React from 'react';
const DisplayData = props => {
const user = props.data;
console.log('Display', user);
switch (props.type) {
case 1: //Twitter
return (
<React.Fragment>
<div className="row lg-padding">
<div className="col-sm-12 lg-padding center">
<img
src={user.pic_url}
alt="profile_picture"
style={{ width: 50 + '%' }}
/>
</div>
<h2>{user.username}</h2>
</div>
<div className="row lg-padding">
<div className="col-sm-4">
<h4>Tweets: {user.nTweets}</h4>
</div>
<div className="col-sm-4">
<h4>Followers: {user.followers}</h4>
</div>
<div className="col-sm-4">
<h4>Followings: {user.followings}</h4>
</div>
</div>
</React.Fragment>
);
case 2: //Instagram
return <React.Fragment />;
default:
return (
<React.Fragment>
<div className="row lg-padding">
<div className="col-sm-12 lg-padding center">
<img
src={user.pic_url}
alt="profile_picture"
style={{ width: 50 + '%' }}
/>
<h2>Instagram_User</h2>
<h4>Posts: ND</h4>
<h4>Followers: ND</h4>
<h4>Followings: ND</h4>
</div>
</div>
</React.Fragment>
);
}
};
export default DisplayData;
How can I update the data in the component or render the component when the data is updated?
Maybe your user_data might to be a state object.
// Somecomponent ...
const [user_data, setUser_data] = useState({
pic_url: 'null',
followers: 'Loading...',
followings: 'Loading...',
nTweets: 'Loading...'
})
/* Rest of stuff */
const handleSubmit = async event => {
/*...*/
const userData = await getData(user.username)
setUser_data(userData)
}
// Then display the stated-stored user_data
<div className="col-sm-12">
**{resolved.display && <DisplayData type={1} data={user_data} />}**
</div>

How can I display array of data in specific div id by click in a button?

I create a component of react. and there one array with some values. so I need to display that value or data in any specific div by clicking in a button.
this is my array in component.
constructor(){
super()
this.state = {
notificaion: [
"Notification-1",
"Notification-3",
"Notification-4",
"Notification-5",
]
}
}
this is my button with click event.
<button onClick={this.getNotification}>{this.state.notificaion.length}</button>
this is the function that I have create. and to push data in specific div.
getNotification = () =>{
return(
this.state.notificaion.map(items =>(
<li key={items}>{items}</li>
))
)
}
here I want to display when buttons is clicked
<strong>{this.getNotification()}</strong>
This is my full code that I have been tried.
import React, {Component} from 'react';
class Menu2 extends Component{
constructor(){
super()
this.state = {
notificaion: [
"Notification-1",
"Notification-3",
"Notification-4",
"Notification-5",
]
}
}
getNotification = () =>{
return(
this.state.notificaion.map(items =>(
<li key={items}>{items}</li>
))
)
}
render(){
return(
<div className="header">
<div className="container">
<div className="row">
<div className="col-lg-12 col-sm-12 col-xs-12">
<div className="text-center mb-20">
<h1>Notificaion Status</h1>
<p>Check notificatin read/unread</p>
</div>
</div>
</div>
<div className="row">
<div className="col-lg-12 col-sm-12 col-xs-12">
<div className="card border-dark mb-3">
<div className="card-body text-dark">
<p className="card-text" style={{textAlign: 'center'}}>
{this.state.notificaion.length > 0
?
<span>You Have <button onClick={this.getNotification}>{this.state.notificaion.length}</button> Unread Notifications</span>
:
<span>You Have <button onClick={this.getNotification}>{this.state.notificaion.length}</button> Unread Notifications}</span>}
</p>
<strong>{this.getNotification()}</strong>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Menu2;
import React, { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
notificaion: [
"Notification-1",
"Notification-3",
"Notification-4",
"Notification-5",
],
notificationHtml: ""
}
}
getNotification = () => {
this.setState({
notificationHtml: this.state.notificaion.map(items => (
<li key={items}>{items}</li>
))
});
}
render() {
return (
<div className="App">
<button onClick={this.getNotification}>{this.state.notificaion.length}</button>
<div>
{this.state.notificationHtml}
</div>
</div>
);
}
}
export default App;
I would implemented as such:
this.state = {
visible: false,
notifications: ...
}
toggleVisibility() =>{
this.setState({
visibile: true
})
}
Don't forget to bind the "toggleVisibility" function. Then
in your component:
<button onClick={this.toggleVisibility}/>
...
{if(this.state.visible){
<strong>this.state.notifications.map(notification,i) =>
<li key={i}>{notification}</li>
</strong>
}
You can add a property showNotification in state. And based on the value of it, we can show the notification.
Also add a method showNotificationHandler that toggles the showNotification value.
class Menu2 extends Component {
constructor() {
super();
this.state = {
notificaion: [
"Notification-1",
"Notification-3",
"Notification-4",
"Notification-5"
],
// adding a property "showNotification"
showNotification: false
};
}
getNotification = () => {
return this.state.notificaion.map(items => <li key={items}>{items}</li>);
};
// method that toggles the "showNotification" value
showNotificationHandler = () => {
this.setState(({ showNotification }) => ({
showNotification: !showNotification
}));
};
render() {
return (
<div className="header">
<div className="container">
<div className="row">
<div className="col-lg-12 col-sm-12 col-xs-12">
<div className="text-center mb-20">
<h1>Notificaion Status</h1>
<p>Check notificatin read/unread</p>
</div>
</div>
</div>
<div className="row">
<div className="col-lg-12 col-sm-12 col-xs-12">
<div className="card border-dark mb-3">
<div className="card-body text-dark">
<p className="card-text" style={{ textAlign: "center" }}>
{this.state.notificaion.length > 0 ? (
<span>
You Have{" "}
<button onClick={this.showNotificationHandler}>
{this.state.notificaion.length}
</button>{" "}
Unread Notifications
</span>
) : (
<span>
You Have{" "}
<button onClick={this.showNotificationHandler}>
{this.state.notificaion.length}
</button>{" "}
Unread Notifications}
</span>
)}
</p>
<strong>
// Depending on the value of "showNotification" we get notification
// if "showNotification" is true then get the notification
{this.state.showNotification && this.getNotification()}
</strong>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Menu2;

React Plaid Component Refreshes the page

Sorry for my English, I'm not a native speaker so please don't minus me too much. I'm a beginner in programming and I'm learning from tutorials found on internet. Today is my first time asking a question on Stack Overflow. It's probably a silly question, I know there are many similar questions, but it's a different issue, it's not a duplicate. Let me move to my question.
I have a react component in which I'm using react-plaid npm package to use Plaid APi. it can be found here react-plaid
My current component code looks like this
Component
import React, {Component} from 'react';
import BuggyApi from "../../services/BuggyApi";
import BlockUi from "react-block-ui";
import ReactPlaid from 'react-plaid'
class Integration extends Component{
state={
plaid_public_key: "",
plaid_public_token: "",
blocking: false,
isSuccess: false,
errorMessage: [],
open: false,
plaidData: [],
};
componentWillMount(){
new BuggyApi().getPlaidPublicKey().then((response)=>{
console.log(response.data);
if(response.status===200){
this.setState({
plaid_public_key: response.data.public_key
});
}
}).catch((error)=>{
})
}
handleOnExit = (error, metadata)=>{
if (error != null) {
console.log('link: user exited');
console.log(error, metadata);
}
};
handleOnLoad =()=>{
console.log('link: loaded');
};
handleOnEvent =(eventname, metadata)=>{
console.log('link: user event', eventname, metadata);
};
handleOnSuccess = (public_token, metadata) => {
console.log('public_token: ' + public_token);
console.log('account ID: ' + metadata.account_id);
};
componentDidMount(){
const script = document.createElement("script");
script.src = "https://cdn.plaid.com/link/v2/stable/link-initialize.js";
script.async = true;
document.body.appendChild(script);
}
render(){
return(
<div className="page-wrapper">
<div className="content container-fluid">
<div className="row">
<div className="col-xs-8">
<h4 className="page-title">Integration</h4>
</div>
<div className="col-xs-4 text-right m-b-30">
</div>
</div>
<div className="row">
<div className="col-md-12">
<div className="text-center">
<h4 className="modal-title">
Link your bank account
</h4>
</div>
<br/>
<br/>
<form>
{(this.state.isSuccess)?
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
<div className="alert alert-success">
<strong>Success!</strong> Settings updated successfully!
</div>
</div>
</div>:null
}
{(this.state.errorMessage.length>0)?
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
<div className="alert alert-danger">
<ul>
{this.state.errorMessage.map((message,i) =><li key={i}>{message}</li>)}
</ul>
</div>
</div>
</div>:null
}
<BlockUi tag="div" blocking={this.state.blocking}>
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
{(this.state.plaid_public_key!=="")?
<div>
<button onClick={() => this.setState({ open: true})}>Open Plaid</button>
<ReactPlaid
clientName="Arshad"
product={["auth"]}
apiKey={this.state.plaid_public_key}
env='sandbox'
open={this.state.open}
onSuccess={(token, metaData) => this.setState({plaidData: metaData})}
onExit={() => this.setState({open: false})}
/>
</div>:null
}
</div>
</div>
</BlockUi>
</form>
</div>
</div>
</div>
</div>
);
};
}
export default Integration;
The problem is when I click the open link button it just shows the Plaid model for few seconds and then refreshes the application page. I'm wondering if someone had the same and can help me out there.
Note:
Please ignore the public key state you can just set it to "c10c40c4ee5eee97764307027f74c2" in apiKey={this.state.plaid_public_key}. I'm getting the public key from the server using axious.
I think I found the issue and though it'd be OK to post my answer on stackoverflow to help others if anyone ever faces the same problem. I was putting the react-plaid-link inside the tags. The react-plaid-link returns a button which according to the html standard a button inside a form without "type" attribute acts like a submit button. Same goes here in my case which I click the the button it submit the form which causes refreshing page. I fixed the issue by just removing the tags. My updated code looks like this.
import React, {Component} from 'react';
import BuggyApi from "../../services/BuggyApi";
import BlockUi from "react-block-ui";
import ReactPlaid from 'react-plaid'
class Integration extends Component{
state={
plaid_public_key: "",
plaid_public_token: "",
blocking: false,
isSuccess: false,
errorMessage: [],
open: false,
plaidData: [],
};
componentWillMount(){
new BuggyApi().getPlaidPublicKey().then((response)=>{
console.log(response.data);
if(response.status===200){
this.setState({
plaid_public_key: response.data.public_key
});
}
}).catch((error)=>{
})
}
handleOnExit = (error, metadata)=>{
if (error != null) {
console.log('link: user exited');
console.log(error, metadata);
}
};
handleOnLoad =()=>{
console.log('link: loaded');
};
handleOnEvent =(eventname, metadata)=>{
console.log('link: user event', eventname, metadata);
};
handleOnSuccess = (public_token, metadata) => {
console.log('public_token: ' + public_token);
console.log('account ID: ' + metadata.account_id);
};
componentDidMount(){
const script = document.createElement("script");
script.src = "https://cdn.plaid.com/link/v2/stable/link-initialize.js";
script.async = true;
document.body.appendChild(script);
}
render(){
return(
<div className="page-wrapper">
<div className="content container-fluid">
<div className="row">
<div className="col-xs-8">
<h4 className="page-title">Integration</h4>
</div>
<div className="col-xs-4 text-right m-b-30">
</div>
</div>
<div className="row">
<div className="col-md-12">
<div className="text-center">
<h4 className="modal-title">
Link your bank account
</h4>
</div>
<br/>
<br/>
{(this.state.isSuccess)?
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
<div className="alert alert-success">
<strong>Success!</strong> Settings updated successfully!
</div>
</div>
</div>:null
}
{(this.state.errorMessage.length>0)?
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
<div className="alert alert-danger">
<ul>
{this.state.errorMessage.map((message,i) =><li key={i}>{message}</li>)}
</ul>
</div>
</div>
</div>:null
}
<BlockUi tag="div" blocking={this.state.blocking}>
<div className="row">
<div className="col-sm-6 col-sm-offset-3">
{(this.state.plaid_public_key!=="")?
<div>
<button onClick={() => this.setState({ open: true})}>Open Plaid</button>
<ReactPlaid
clientName="Arshad"
product={["auth"]}
apiKey={this.state.plaid_public_key}
env='sandbox'
open={this.state.open}
onSuccess={(token, metaData) => this.setState({plaidData: metaData})}
onExit={() => this.setState({open: false})}
/>
</div>:null
}
</div>
</div>
</BlockUi>
</div>
</div>
</div>
</div>
);
};
}
export default Integration;
Sometimes you need to put the Plaid button inside a form element, in which case, just pass (e) => e.preventDefault() in as the onClick handler
<ReactPlaid
clientName="Arshad"
product={["auth"]}
apiKey={this.state.plaid_public_key}
env='sandbox'
open={this.state.open}
onSuccess={(token, metaData) => this.setState({plaidData: metaData})}
onExit={() => this.setState({open: false})}
onClick={(e) => e.preventDefault()}
/>

Not able to display list items using map in reactjs?

I have a userlist which contains name and email id of each user. I want to display it using the .map() method on userlist state variable. I have created displayusers() function to display the users but I am getting failed to compile error.
Code:
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props);
this.state = {
userlist:[
{'name':'Rohan Singh',
'email':'rohan#gmail.com'
},
{'name':'Mohan Singh',
'email':'mohan#gmail.com'
},
{'name':'Rakesh Roy',
'email':'rakesh#gmail.com'
},
{'name':'Sunil Shah',
'email':'sunil#gmail.com'
}]
}
}
displayusers(){
return this.state.userlist.map( user => {
return(
<div className="item-card">
<div className="sub">
<div className="type">Username: {user.name}</div>
<div className="members">Email: {user.email}</div>
</div>
<div className="del-wrap">
<img src={require("../../images/cancel.svg")}/>
</div>
</div>
);
})
}
render() {
return(
<div className="users-wrap">
<h1>Users</h1>
<div className="task-content">
<div className="user-wrap">
<div className="users">
{this.displayusers()}
</div>
</div>
</div>
</div>
);
}
}
export default App;
I think you forgot about adding a key attribute to the element and there's missing </div> closing tag in your map function.
See the corrected code:
displayusers(){
return this.state.userlist.map( user => {
return(
<div className="item-card" key={user.name}>
<div className="sub">
<div className="type">Username: {user.name}</div>
<div className="members">Email: {user.email}</div>
</div>
<div className="del-wrap">
<img src={require("../../images/cancel.svg")}/>
</div>
</div>
);
});
}
You need to bind your displayusers function to this. You can do that in the constructor.
Update your code as following:
import React, { Component } from 'react';
class App extends Component {
constructor(props){
super(props);
this.state = {
userlist:[
{'name':'Rohan Singh',
'email':'rohan#gmail.com'
},
{'name':'Mohan Singh',
'email':'mohan#gmail.com'
},
{'name':'Rakesh Roy',
'email':'rakesh#gmail.com'
},
{'name':'Sunil Shah',
'email':'sunil#gmail.com'
}]
};
this.displayusers = this.displayusers.bind(this); // you need to add this line
}
displayusers(){
return this.state.userlist.map((user, index) => {
return(
<div className="item-card" key={index}>
<div className="sub">
<div className="type">Username: {user.name}</div>
<div className="members">Email: {user.email}</div>
</div>
<div className="del-wrap">
<img src={require("../../images/cancel.svg")}/>
</div>
);
})
}
render() {
return(
<div className="users-wrap">
<h1>Users</h1>
<div className="task-content">
<div className="user-wrap">
<div className="users">
{this.displayusers()}
</div>
</div>
</div>
</div>
);
}
}
export default App;

How to add custom clickHandler for a specifc row

To set the context, I am new to REACT. I am working on a sample app where I need to display the trade data in tabular format. If you select the row, delete button on the extreme right should be displayed. Otherwise it should be hidden.
Instead of toggling with the display button, I am just trying to show and hide a text first. I was able to do that. Only thing which happens is that the text gets toggled for all the rows.
I was trying number of things to get this working. The code below is work in progress and I am not sure what to do next,
import React from 'react';
class TradeTableView extends React.Component {
constructor(){
super()
this.state = {
data: []
}
this.handleClickEvent = this.handleClickEvent.bind(this);
}
handleClickEvent(event) {
const name = event.target.name;
console.log('Name in handleClickEvent is ' + name);
}
componentDidMount() {
console.log('inside component did mount..');
fetch('http://localhost:3004/row')
.then(response => {
return response.json();})
.then(responseData => {console.log(responseData); return responseData;})
.then((data) => {
// jsonItems = JSON.parse(items);
this.setState({data: data});
});
}
render() {
return(
<div className="Table">
<div className="Heading">
<div className="Cell">
<p>Trade Date</p>
</div>
<div className="Cell">
<p>Commodity</p>
</div>
<div className="Cell">
<p>Side</p>
</div>
<div className="Cell">
<p>Quanity</p>
</div>
<div className="Cell">
<p>Price</p>
</div>
<div className="Cell">
<p>Counterparty</p>
</div>
<div className="Cell">
<p>Location</p>
</div>
<div className="Cell">
<p></p>
</div>
</div>
{this.state.data.map((item, key) => {
let prop1 = 'shouldHide'+key;
console.log('The prop is ' + prop1);
return (
<div ref={prop1} key={key} className="Row" onClick={this.handleClickEvent}>
<div className="Cell">
<p>{item.a}</p>
</div>
<div className="Cell">
<p>{item.b}</p>
</div>
<div className="Cell">
<p>{item.c}</p>
</div>
<div className="Cell">
<p>{item.d}</p>
</div>
<div className="Cell">
<p>{item.e}</p>
</div>
<div className="Cell">
<p>{item.f}</p>
</div>
<div className="Cell">
<p>{item.f}</p>
</div>
<div className="Cell">
<p onClick={this.handleClickEvent}>{this.state.prop1 ? 'Sample Text':'Some Text'}</p>
</div>
</div>
)
})}
</div>
);
}
}
export default TradeTableView;
This is my component. If you can let me know how to toggle the text only for a particular row, I can most probably use that know how to toggle the button(my original use case) and then delete the row on click of the button. I will really appreciate your help.
P.S I was able to toggle the text.You may not find logic on thi.state.prop1 in my code above because I was trying to modify the code to make it work for a single row. And finally I got in a state where it is not working for all the rows and obviously not for a single row. To sum up, my problem is to identify the unique row and dislay a section only for that row.
I've added a currentSelectedRow property to state to keep track of the selected row. Below is the code with minimal configuration.
import React from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
class TradeTableView extends React.Component {
constructor() {
super()
this.state = {
data: [{id:1,val:11},{id:2,val:22},{id:3,val:33}],
currentSelectedRow : -1
}
}
handleClickEvent = (event, key) =>{
this.setState({ currentSelectedRow: key})
}
render() {
return (
<div className="Table">
{this.state.data.map((item, key) => {
return (
<div key={key} className="Row" onClick={(e) => this.handleClickEvent(e, key)}>
<div className="Cell">
<p>{item.id}</p>
</div>
<div className="Cell">
<p>{item.val}</p>
</div>
<div className="Cell">
<p onClick={(e) => this.handleClickEvent(e, key)}>{this.state.currentSelectedRow === key ? 'Row Selected' : 'Row Not Selected'}</p>
</div>
</div>
)
})}
</div>
);
}
}
render(<TradeTableView />, document.getElementById('root'));
Here is the working example
Change your handleClickevent like this:
handleClickEvent(event, index) {
const name = event.target.name;
console.log("index is", index);
const stateData = [...this.state.data];
stateData[index]= "some new value"
this.setState({
data: stateData,
})
console.log('Name in handleClickEvent is ' + name);
}
change how you are attaching click handler to
onClick={(event) => this.handleClickEvent(event, key)}
Something along these lines is needed as per my understanding of the question.

Categories

Resources