How to load a new component on button click in ReactJs? - javascript

I created a main component in ReactJs called MainPage (using Material-UI).
import React from 'react';
import Grid from '#material-ui/core/Grid';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import Card from '#material-ui/core/Card';
import CardContent from '#material-ui/core/CardContent';
import withStyles from '#material-ui/core/styles/withStyles';
const styles = theme => ({
card: {
minWidth: 350,
},
button: {
fontSize: '12px',
margin: theme.spacing.unit,
minWidth: 350
},
extendedIcon: {
marginRight: theme.spacing.unit,
}
});
class MainPage extends React.Component {
constructor() {
super();
}
render() {
const {
classes
} = this.props;
return ( <
React.Fragment >
<
CssBaseline / >
<
Grid container spacing = {
0
}
direction = "column"
alignItems = "center"
justify = "center"
style = {
{
minHeight: '100vh'
}
} >
<
form onSubmit = {
this.handleSubmit
} >
<
Card className = {
classes.card
} >
<
CardContent >
<
Grid item xs = {
3
} >
<
Button variant = "contained"
size = "medium"
color = "primary"
className = {
classes.button
}
type = "submit"
value = "single" >
ButtonA <
/Button> <
/Grid> <
Grid item xs = {
3
} >
<
Button variant = "contained"
size = "medium"
color = "primary"
className = {
classes.button
}
type = "submit"
value = "batch" >
ButtonB <
/Button> <
/Grid> <
/CardContent> <
/Card> <
/form> <
/Grid> <
/React.Fragment>
);
}
}
export default withStyles(styles)(MainPage);
I want to load a new component (either CompA or CompB, depending on which button was clicked - ButtonA or ButtonB) on button click. A new component should completely replace a current component - I mean that it should be loaded in a whole screen (not anywhere next to buttons).
How can I do it?
UPDATE:
I want to replace MainPage component, not just render on top of it.
This is how I load MainPage:
index.js
import React from 'react';
import { render } from 'react-dom';
import MainPage from './components/MainPage';
const View = () => (
<div>
<MainPage/>
</div>
);
render(<View />, document.getElementById('root'));

You can create a different component to handle the state and add an if statement in that component to handle the view that you want to render.
You can see the example here codesandbox.io/embed/6wx2rzjrr3
App.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Main from "./Main";
import View1 from "./View1";
import View2 from "./View2";
import "./styles.css";
class App extends Component {
state = {
renderView: 0
};
clickBtn = e => {
this.setState({
renderView: +e.target.value
});
};
render() {
switch (this.state.renderView) {
case 1:
return <View1 />;
case 2:
return <View2 />;
default:
return <Main clickBtn={this.clickBtn} />;
}
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Main.js
import React from "react";
export default props => (
<>
Main view{" "}
<button value={1} onClick={props.clickBtn}>
View 1
</button>{" "}
<button value={2} onClick={props.clickBtn}>
View 2
</button>{" "}
</>
);
View1.js
import React from "react";
export default props => "View 1";
View2.js
import React from "react";
export default props => "View 2";

In your index.js you can use
const View = () => (
<div>
<MainPage condition='something' />
</div>
);
Then in you main page:
class MainPage extends React.Component {
constructor() {
super();
}
myCondition1() {
return (
<Component1 />
);
}
myCondition2() {
return (
<Component2 />
);
}
render() {
const { condition} = this.props;
return (
{condition === 'something' ? this.myCondition1() : this.myCondition2()}
)
}
}
UPDATE
Here's an example with a simple button:
class Condition1 extends React.Component {
render() {
return (
<div>Condition 1</div>
);
}
}
class Condition2 extends React.Component {
render() {
return (
<div>Condition 2</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
condition: true
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(condition) {
this.setState( {condition} )
}
render() {
const { condition } = this.state;
return (
<div>
<button onClick={() => this.handleClick(true)}>Condition1</button>
<button onClick={() => this.handleClick(false)}>Condition2</button>
{condition === true ? <Condition1 /> : <Condition2 />}
</div>
)
}
}
ReactDOM.render( < App / > ,
document.getElementById('root')
);
<script src="https://unpkg.com/react#16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js" crossorigin></script><div id="root" />

Related

How to update one child component alone in React Js

I was making react version of game Bingo. I added 25 buttons which are the child components.
Initially i have empty values in each button. Then on each click, i was trying to update the clicked button's values from 1 to 25.
But when i click on one button, to update the button label, all button's values are getting updated. Can anyone suggest the reason behind that?
App.js
import React from "react";
import "./styles.css";
import GameContainerOne from "./GameContainerOne";
export default function App() {
return (
<div className="App">
<GameContainerOne />
</div>
);
}
GameContainerOne.js
import React from "react";
import ButtonBox from "./ButtonBox";
class GameContainerOne extends React.Component {
constructor(props) {
super(props);
this.state = {
btnLabel: 0
};
}
handleClicked = () => {
if (this.state.btnLabel < 25) {
this.setState({ btnLabel: ++this.state.btnLabel });
console.log("after", this.state.btnLabel);
}
};
render() {
let menuItems = [];
let key = 0;
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
let index = "" + i + j;
// console.log(index)
key++;
menuItems.push(
<ButtonBox
key={key}
index={index}
value={this.state.btnLabel}
handleClicked={this.handleClicked.bind(this)}
/>
);
}
}
return <div className="wrapper">{menuItems}</div>;
// this.handleButtonBox()
}
}
export default GameContainerOne;
ButtonBox.js
import React from "react";
import Button from "#material-ui/core/Button";
class ButtonBox extends React.Component {
constructor(props) {
super(props);
this.state = {
initialBtnColor: "Default",
selectedBtnColor: "Primary"
};
}
handleClick = () => {
// console.log("before",this.state.btnLabel)
this.setState({ initialBtnColor: "Primary" });
return this.props.handleClicked;
};
render() {
console.log("Key=", this.props);
// const { index } = this.props.index;
console.log("Key=", this.props.index);
return (
<div>
<Button
variant="contained"
color={this.state.initialBtnColor}
onClick={this.props.handleClicked}
>
{this.props.value}
</Button>
</div>
);
}
}
export default ButtonBox;
Please find the codesandbox link : https://codesandbox.io/s/bingo-game-glk8v
Move the btnLabel state into the ButtonBox.
Example (using hooks):
// ButtonBox.js
import React from "react";
import Button from "#material-ui/core/Button";
function ButtonBox(props) {
const [buttonColor, setButtonColor] = React.useState("Default");
const [value, setValue] = React.useState(props.startValue);
return (
<div>
<Button
variant="contained"
color={buttonColor}
onClick={() => {
setValue(value + 1);
setButtonColor("Primary");
props.handleClicked(props.index);
}}
>
{value}
</Button>
</div>
);
}
export default ButtonBox;
// GameContainerOne.js
import React from "react";
import ButtonBox from "./ButtonBox";
function GameContainerOne(props) {
const handleClicked = React.useCallback(btnIndex => {
// Called after a button is clicked
}, []);
let menuItems = [];
let key = 0;
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
let index = "" + i + j;
key++;
menuItems.push(
<ButtonBox
key={key}
index={index}
startValue={0}
handleClicked={handleClicked}
/>
);
}
}
return <div className="wrapper">{menuItems}</div>;
}
export default GameContainerOne;
You change the state on click which is the source of labels for all the buttons.
You could have a separate state for all the buttons to avoid that and changed them based on the index on the button clicked.

render function automatically trigger onClick props function issue in React?

In parent component have one child component. In Child component I have one props with click function. In that click function, triggering before click while rendering component. I need to restrict that click function in render. Check below my code...
I have parent component is APP.
import React, { Component } from "react";
import { withRouter } from 'react-router-dom';
import { connect } from "react-redux";
import { Pagination } from './../Common/index';
class App extends Component {
handlePageination = (current) => {
console.log('trigger')
}
render() {
return (
<main className="main-block">
<Pagination total={userList.length>0 ? totalCount : 0} range={10} initial={0} rowClick={this.handlePageination} count={currentPageNumber} />
</main>
)
}
}
export default App;
Child component...
import React, { Component } from "react";
import ReactPaginate from 'react-paginate';
import { ORIGIN_PATH } from "./../../../utilities/consts";
import "./Pagination.css";
class Pagination extends Component {
handlePageClick = (e) => {
this.props.rowClick(e.selected)
}
render() {
const { range, initial } = this.props;
let { count, total } = this.props;
count = count + 10;
total = parseInt(total, 10);
if(count===0 && total < 10) {
count = total
} else if(count >= total) {
count = total
}
return(
<div className="pagination-block">
<p>Showing {count} out of {total} results</p>
{<ReactPaginate previousLabel={<img src={ORIGIN_PATH + "/images/icons/polygon-prev-icon#3x.png"} alt="Prev" />}
nextLabel={<img src={ORIGIN_PATH + "/images/icons/polygon-next-icon#3x.png"} alt="Next" />}
breakLabel={...}
breakClassName={"break-me"}
pageCount={total/range}
marginPagesDisplayed={2}
pageRangeDisplayed={range}
onPageChange={this.handlePageClick}
containerClassName={"pagination"}
subContainerClassName={"pages pagination"}
initialPage={initial}
activeClassName={"active"} />}
</div>
)
}
}
export default Pagination;
change this in your child component while your using click function inside render user arrow function
onPageChange={(e) => this.handlePageClick()}
In your Pagination component render
Change
onPageChange={this.handlePageClick}
To
onPageChange={e => this.handlePageClick(e)}
Corrected code below
import React, { Component } from "react";
import ReactPaginate from 'react-paginate';
import { ORIGIN_PATH } from "./../../../utilities/consts";
import "./Pagination.css";
class Pagination extends Component {
handlePageClick = (e) => {
this.props.rowClick(e.selected)
}
render() {
const { range, initial } = this.props;
let { count, total } = this.props;
count = count + 10;
total = parseInt(total, 10);
if(count===0 && total < 10) {
count = total
} else if(count >= total) {
count = total
}
return(
<div className="pagination-block">
<p>Showing {count} out of {total} results</p>
{<ReactPaginate previousLabel={<img src={ORIGIN_PATH + "/images/icons/polygon-prev-icon#3x.png"} alt="Prev" />}
nextLabel={<img src={ORIGIN_PATH + "/images/icons/polygon-next-icon#3x.png"} alt="Next" />}
breakLabel={...}
breakClassName={"break-me"}
pageCount={total/range}
marginPagesDisplayed={2}
pageRangeDisplayed={range}
onPageChange={e => this.handlePageClick(e)}
containerClassName={"pagination"}
subContainerClassName={"pages pagination"}
initialPage={initial}
activeClassName={"active"} />}
</div>
)
}
}
export default Pagination;

How to link onclick callback to call external file

I created array of buttons, let say I have 20 buttons. I have 20 mp3 files as well. Now what i want to do is to link the button callback "onclick" with a
specific .mp3 file. So that, when the button number 5 is clicked, the 5th mp3 will be executed. how can I achieve this task by modifying the below
posted code? please provide an example.
note: the mp3 files are save locally on the hard drive.
please let me know how should i pass value to onClick callback
code:
import React from "react";
import ReactDOM from "react-dom";
import createReactClass from "create-react-class";
var arrButtons = [];
var buttonStyle = {
margin: "10px 10px 10px 0"
};
class ButtonClicks extends React.Component {
constructor(props) {
super(props);
this.onClickFunction = this.onClickFunction.bind(this);
}
onClickFunction() {
console.log("button ");
console.log(this.props.log);
}
render() {
for (let i = 0; i < 10; i++) {
//Moved your loop outside render()'s return
arrButtons.push(
<button style={buttonStyle} onClick={this.onClickFunction}>
{i}
{this.props.i}
</button>
);
}
return (
<div>
{arrButtons} {/*Very important to wrap the buttons inside a div*/}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<ButtonClicks />, rootElement);
export default ButtonClicks;
You would benefit from using JS's .map and creating a button that has a unique onClick passing that specific mp3's id back into your onClick function. From there you can lookup by id, then play only that specific file.
import React from "react";
import ReactDOM from "react-dom";
import createReactClass from "create-react-class";
class ButtonClicks extends React.Component {
constructor(props) {
super(props);
this.state = {mp3Files}
this.onClickFunction = this.onClickFunction.bind(this);
}
onClickFunction(mp3UniqueIdToLookup) {
console.log("button ");
console.log(this.props.log);
//Here you would search your files for the mp3 with the corresponding id and then play that one only.
}
render() {
const buttonStyle = {
margin: "10px 10px 10px 0"
};
return (
<div>
{this.state.mp3Files.map((index, ele) => {
return <button style={buttonStyle} key={index} onClick={() => this.onClickFunction(ele.id)}/>
})}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<ButtonClicks />, rootElement);
export default ButtonClicks;
Here is my solution. While doing loop you can pass the no to event handler function and access the no. This is how it works when you do looping
ES5 way
import React, {Component} from "react";
import ReactDOM from "react-dom";
import createReactClass from "create-react-class";
var arrButtons = [];
var buttonStyle = {
margin: "10px 10px 10px 0"
};
class ButtonClicks extends Component {
constructor(props) {
super(props);
this.onClickFunction = this.onClickFunction.bind(this);
}
onClickFunction(no) {
console.log("Here you will get button no. if you click button 5 you will get button no 5 and you can pass the same to log");
console.log(this.props.log(no));
}
render() {
for (let i = 1; i <=10; i++) {
arrButtons.push(
<button style={buttonStyle} onClick={this.onClickFunction(i)}>
{i}
{this.props.i}
</button>
);
}
return (
<div>
{arrButtons} {/*Very important to wrap the buttons inside a div*/}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<ButtonClicks />, rootElement);
export default ButtonClicks;
ES6 way
import React, {Component} from "react";
import ReactDOM from "react-dom";
import createReactClass from "create-react-class";
var arrButtons = [];
var buttonStyle = {
margin: "10px 10px 10px 0"
};
class ButtonClicks extends Component {
constructor(props) {
super(props);
}
onClickFunction = (no) => {
console.log("Here you will get button no. if you click button 5 you will get button no 5 and you can pass the same to log");
console.log(this.props.log(no));
}
render() {
for (let i = 1; i <=10; i++) {
arrButtons.push(
<button style={buttonStyle} onClick={this.onClickFunction(i)}>
{i}
{this.props.i}
</button>
);
}
return (
<div>
{arrButtons} {/*Very important to wrap the buttons inside a div*/}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<ButtonClicks />, rootElement);
export default ButtonClicks;
i suggest that you give your buttons the IDs of their index and receiving them in the onClickFunction like this
onClickFunction(e) {
var mp3Index = parseInt(e.target.id);
console.log("button ");
console.log(this.props.log);
}
render() {
for (let i = 0; i < 10; i++) {
//Moved your loop outside render()'s return
arrButtons.push(
<button id={i} style={buttonStyle} onClick={this.onClickFunction}>
{i}
{this.props.i}
</button>
);
}
return (
<div>
{arrButtons} {/*Very important to wrap the buttons inside a div*/}
</div>
);
}
}
from there you may proceed on how to use their index.

React switching between queues (lists) bug

I'm working on an app that keeps track of salespeople's availability based on being either "Available" or "With Client".
Here's the bug I'm having. I'll use an example:
2 salespeople have been added to the app. The order in which they have been added to the app seems to matter in a way I don't expect to. For example, if the first salesperson I've added is James and the second is Rick, If I click on the button next to Rick that reads "Helped A Customer", James will now populate both the "Available" and the "With Client" tables, and Rick will have disappeared.
However if I click on them in a certain order, it works fine. For example, in the same situation as the example above, if I click on James' "Helped A Customer" first, then Rick's "Helped A Customer", then James' "No Longer With Customer", then Rick's "No Longer With Customer", it behaves as expected.
Here's the github project, you can clone it and try it out yourselves:
https://github.com/jackson-lenhart/salesperson-queue
I'll post what I think is the most relevant code here as well:
main.js:
import React from "react";
import { render } from "react-dom";
import shortid from "shortid";
import deepCopy from "deep-copy";
import AddForm from "./add-form";
import Available from "./available";
import WithClient from "./with-client";
class Main extends React.Component {
constructor() {
super();
this.state = {
queue: {
available: [],
withClient: [],
unavailable: []
},
currName: ""
};
this.addToQueue = this.addToQueue.bind(this);
this.removeFromQueue = this.removeFromQueue.bind(this);
this.handleInput = this.handleInput.bind(this);
this.move = this.move.bind(this);
}
addToQueue(name) {
let newQueue = deepCopy(this.state.queue);
newQueue.available = this.state.queue.available.concat({
name,
id: shortid.generate()
});
this.setState({
queue: newQueue
});
}
removeFromQueue(id) {
let newQueue = deepCopy(this.state.queue);
for (let k in this.state.queue) {
newQueue[k] = this.state.queue[k].filter(x =>
x.id !== id
);
}
this.setState({
queue: newQueue
});
}
move(id, from, to) {
this.setState(prevState => {
let newQueue = deepCopy(prevState.queue);
let temp = newQueue[from].find(x => x.id === id);
newQueue[from] = prevState.queue[from].filter(x =>
x.id !== id
);
newQueue[to] = prevState.queue[to].concat(temp);
return {
queue: newQueue
};
});
}
handleInput(event) {
this.setState({
currName: event.target.value
});
}
render() {
return (
<div>
<AddForm
addToQueue={this.addToQueue}
handleInput={this.handleInput}
currName={this.state.currName}
/>
<Available
available={this.state.queue.available}
move={this.move}
removeFromQueue={this.removeFromQueue}
/>
<WithClient
withClient={this.state.queue.withClient}
move={this.move}
removeFromQueue={this.removeFromQueue}
/>
</div>
);
}
}
render(
<Main />,
document.body
);
add-form.js:
import React from "react";
class AddForm extends React.Component {
constructor() {
super();
this.clickWrapper = this.clickWrapper.bind(this);
}
clickWrapper() {
this.props.addToQueue(this.props.currName);
}
render() {
return (
<div>
<input
type="text"
onChange={this.props.handleInput}
/>
<button onClick={this.clickWrapper}>
<strong>Add To Queue</strong>
</button>
</div>
);
}
}
export default AddForm;
available.js:
import React from "react";
import Salesperson from "./salesperson";
class Available extends React.Component {
render() {
const style = {
item: {
padding: "10px"
},
available: {
padding: "20px"
}
};
let available;
this.props.available.length === 0 ?
available = (
<p>None available.</p>
) : available = this.props.available.map(x =>
<div key={x.id} style={style.item}>
<Salesperson
key={x.id}
id={x.id}
name={x.name}
move={this.props.move}
removeFromQueue={this.props.removeFromQueue}
parent={"available"}
/>
</div>
);
return (
<div style={style.available}>
<h1>Available</h1>
{available}
</div>
);
}
}
export default Available;
salesperson.js:
import React from "react";
import DeleteButton from "./delete-button";
import HelpedButton from "./helped-button";
import NlwcButton from "./nlwc-button";
class Salesperson extends React.Component {
render() {
const style = {
name: {
padding: "10px"
},
button: {
padding: "5px"
}
};
let moveButton;
switch(this.props.parent) {
case "available":
moveButton = (
<HelpedButton
move={this.props.move}
id={this.props.id}
style={style.button}
/>
);
break;
case "withClient":
moveButton = (
<NlwcButton
move={this.props.move}
removeFromQueue={this.props.removeFromQueue}
id={this.props.id}
style={style.button}
/>
);
break;
default:
console.error("Invalid parent:", this.props.parent);
}
return (
<div>
<span style={style.name}>{this.props.name}</span>
{moveButton}
<DeleteButton
removeFromQueue={this.props.removeFromQueue}
name={this.props.name}
id={this.props.id}
style={style.button}
/>
</div>
);
}
}
export default Salesperson;
helped-button.js:
import React from "react";
class HelpedButton extends React.Component {
constructor() {
super();
this.clickWrapper = this.clickWrapper.bind(this);
}
clickWrapper() {
this.props.move(this.props.id, "available", "withClient");
}
render() {
return (
<span style={this.props.style}>
<button onClick={this.clickWrapper}>
<strong>Helped A Customer</strong>
</button>
</span>
);
}
}
export default HelpedButton;
This was just a typo on my part. No longer an issue. Here's the commit that fixed the typo:
https://github.com/jackson-lenhart/salesperson-queue/commit/b86271a20ac8b700bec1e15e001b0c6ef57adb8b

Show the last index in an array when I click (in an array that continues to be updated)

I am near the end of creating my application.
So it is for banks accounts where they ask you to give the first letter of your password, then for example fourth, etc.
I'm tired of counting on my own so I created this app.
But there is the last bug that I don't know how to fix.
So when I press "1" I get "1 - H", and then when I press "4" I want to get:
"1 - H" (clicked before)
"4 - X" (clicked just now)
but instead, I get:
"4 - X" (clicked just now)
"4 - X" (clicked just now)
So it is caused by the way handleResults() function works inside my Input component, but for now it is my only concept how to approach this...
import React, { Component } from 'react';
import TextField from 'material-ui/TextField';
import './style.css';
import Buttons from '../Buttons';
import Results from '../Results';
class Input extends Component {
constructor(props) {
super(props);
this.state = {
password: 'Hh9Xzke2ayzcEUPHuIfS',
selectedButtons: [],
};
this.handleButtonSelectTwo = this.handleButtonSelectTwo.bind(this);
}
handleInputChange(pass) {
this.setState({ password: pass });
}
handleButtonSelectTwo(selected) {
this.setState({
selectedButtons: [...this.state.selectedButtons, selected],
});
}
handleResults() {
return this.state.selectedButtons.map(el => (
<Results key={el} appState={this.state} />
));
}
render() {
return (
<div>
<div className="Input-textfield">
<TextField
hintText="Paste your password here to begin"
value={this.state.password}
onChange={event => this.handleInputChange(event.target.value)}
/>
</div>
<div>
<Buttons
handleButtonSelectOne={this.handleButtonSelectTwo}
array={this.state.password.length}
/>
{this.handleResults()}
</div>
</div>
);
}
}
export default Input;
and here is Results component code:
import React, { Component } from 'react';
import _ from 'lodash';
import Avatar from 'material-ui/Avatar';
import List from 'material-ui/List/List';
import ListItem from 'material-ui/List/ListItem';
import './style.css';
const style = {
avatarList: {
position: 'relative',
left: -40,
},
avatarSecond: {
position: 'relative',
top: -40,
left: 40,
},
};
class Results extends Component {
resultsEngine(arg) {
const { selectedButtons, password } = this.props.appState;
const passwordArray = password.split('').map(el => el);
const lastSelectedButton = _.last(selectedButtons);
const passwordString = passwordArray[_.last(selectedButtons) - 1];
if (arg === 0) {
return lastSelectedButton;
}
if (arg === 1) {
return passwordString;
}
return null;
}
render() {
if (this.props.appState.selectedButtons.length > 0) {
return (
<div className="test">
<List style={style.avatarList}>
<ListItem
disabled
leftAvatar={<Avatar>{this.resultsEngine(0)}</Avatar>}
/>
<ListItem
style={style.avatarSecond}
disabled
leftAvatar={<Avatar>{this.resultsEngine(1)}</Avatar>}
/>
</List>
</div>
);
}
return <div />;
}
}
export default Results;
Anyone has an idea how should I change my code inside handleResults() function to achieve my goal? Any help with solving that problem will be much appreciated.
Buttons component code:
import React from 'react';
import OneButton from '../OneButton';
const Buttons = props => {
const arrayFromInput = props.array;
const buttonsArray = [];
for (let i = 1; i <= arrayFromInput; i++) {
buttonsArray.push(i);
}
const handleButtonSelectZero = props.handleButtonSelectOne;
const allButtons = buttonsArray.map(el => (
<OneButton key={el} el={el} onClick={handleButtonSelectZero} />
));
if (arrayFromInput > 0) {
return <div>{allButtons}</div>;
}
return <div />;
};
export default Buttons;
And OneButton code:
import React, { Component } from 'react';
import RaisedButton from 'material-ui/RaisedButton';
const style = {
button: {
margin: 2,
padding: 0,
minWidth: 1,
},
};
class OneButton extends Component {
constructor() {
super();
this.state = { disabled: false };
}
handleClick() {
this.setState({ disabled: !this.state.disabled });
this.props.onClick(this.props.el);
}
render() {
return (
<RaisedButton
disabled={this.state.disabled}
key={this.props.el}
label={this.props.el}
style={style.button}
onClick={() => this.handleClick()}
/>
);
}
}
export default OneButton;
In your resultsEngine function in the Results component you are specifying that you always want the _.last(selectedButtons) to be used. This is what it is doing, hence you always see the last button clicked. What you actually want is the index of that iteration to show.
const lastSelectedButton = selectedButtons[this.props.index];
const passwordString = passwordArray[selectedButtons[this.props.index]];
To get an index you have to create and pass one in, so create it when you map over the selected Buttons in the handleResults function in your Input component.
handleResults() {
return this.state.selectedButtons.map((el, index) => (
<Results key={el} appState={this.state} index={index} />
));
}

Categories