I'm trying to create a web-app with the front end in React and backend in Flask. I have a dropdown which gets populated by the flask JSON which is basically a list of companies. All total there are around 5 components, the first one is the App.js, second is the CompanySelection.js, the third one is the Chart.js where I want to return my graphs and all.
So in theCompanySelection.js when I change the dropdown selection the updated company name does not go into Charts.js, i.e. the other component. I guess when this part gets solved similarly I can pass the values from one component to the other easily.
These are my three code files:
App.js
import React from "react";
import { CompanyContextProvider } from "./context";
import Dropdown from 'react-dropdown';
import 'react-dropdown/style.css';
import Header from "./Header";
import CompanySelection from "./CompanySelection/CompanySelection.js";
import Charts from "./Charts/Chart.js";
import axios from 'axios';
class App extends React.Component{
state = {
companies: [],
firstCompany: {},
firstCompanyName: ''
};
componentDidMount() {
fetch('http://127.0.0.1:5001/algo/loc')
.then(res => res.json())
.then(data => {
this.setState({companies: data,
firstCompany: data[0],
firstCompanyName: data[0].value}, () =>
console.log(this.state.companies, this.state.firstCompany, this.state.firstCompanyName));
console.log('')
}).catch(function (error) {
console.log(error);
});
}
selectedValueHandler = (selectedValue) => {
this.setState({
firstCompanyName: selectedValue
})
}
render() {
const { selectedValue } = this.state.firstCompanyName;
console.log('change value',selectedValue)
return (
<div className="app">
<Header/>
<CompanySelection companies= {this.state.companies} selectedCompany={this.state.firstCompany} setSelectedCompany={this.state.firstCompanyName} selectedValueHandler = {this.selectedValueHandler}/>
<Charts companies= {this.state.companies} selectedCompany={this.state.firstCompany} setSelectedCompany={selectedValue}/>
</div>
);
}
} ;
export default App;
CompanySelection.js
import { h, render, Component} from 'preact';
import style from './style.css';
import { useContext } from "preact/hooks";
import { CompanyContext } from "../context";
class CompanySelection extends Component {
constructor(props)
{
super(props);
}
render(_, { value }) {
const companies = this.props.companies;
const selectedCompany = this.props.selectedCompany;
const setSelectedCompany = this.props.setSelectedCompany;
var onChange = (e) =>{
console.log("In on change");
this.setState({ value: e.target.value });
const setSelectedCompany = e.target.value;
console.log("Selected", e.target.value);
const companies = this.props.companies;
const selectedCompany = this.props.selectedCompany;
this.props.selectedValueHandler(e.target.value);
}
if (typeof companies !== 'undefined')
{
var options = companies.map((comp) =>
<option
key={comp.label}
value={comp.value}
>
{comp.label}
</option>
);
}
else {
var options = [{value: 'A', label: 'B'}].map((comp) =>
<option
key={comp.label}
value={comp.value}
>
{comp.label}
</option>
);
}
return (
<fragment class={style.fragment}>
<label class={style.label}> Company </label>
<select value={value} onChange={onChange} class={style.dropdown}>
{options}
</select>
</fragment>
);
}
}
render(<CompanySelection />, document.body);
export default CompanySelection;
Chart.js
import { h, render, Component } from 'preact';
import style from './style.css';
import { VictoryChart, VictoryLine, VictoryScatter, VictoryLabel} from 'victory';
import { useContext } from "preact/hooks";
import { CompanyContext } from "../context";
class Charts extends Component {
constructor(props)
{
super(props);
}
render(_, { value }) {
const companies = this.props.companies;
const selectedCompany = this.props.selectedCompany;
const setSelectedCompany = this.props.setSelectedCompany;
console.log('list of companies chart', companies)
console.log('chart input', setSelectedCompany)
if (typeof selectedCompany !== 'undefined') {
var comp = selectedCompany;
}
else {
var comp = '';
}
console.log("comp", comp);
return (
<fragment>
<div class={style.chart}>
<VictoryChart domain={[0, 10]}>
<VictoryLabel text={comp} x={225} y={30} textAnchor="middle"/>
<VictoryLine
style={{ data: { stroke: "blue", strokeWidth: 3 } }}
y={(d) => d.x}
/>
<VictoryScatter
symbol="star"
size={8}
style={{ data: { fill: "red" }}}
data={[{ x: 5, y: 5 }]}
/>
<VictoryScatter
symbol="circle"
size={8}
style={{ data: { fill: "red" }}}
data={[{ x: 7, y: 7 }]}
/>
</VictoryChart>
</div>
</fragment>
);
}
}
render(<Charts />, document.body);
export default Charts;
I have taken reference of this code from this stackoverflow post: How to pass data from one component to another component in onchange using React js
However when I see the output of this line of code: const { selectedValue } = this.state.firstCompanyName;
console.log('change value',selectedValue)
I get that change value undefined, which means the values are not getting passed on. I'm very new to react and haven't been able to solve this yet. Any help is much appreciated.
P.S. The components pass on well to the <CompanySelection..../>
However when I see the output of this line of code: const { selectedValue } = this.state.firstCompanyName;
console.log('change value',selectedValue)
It will be undefined, here you are trying to destructure selectedValue from a string firstCompanyName, as long as this.state.firstCompanyName is not an object with a key named selectedValue it will be undefined. Instead do this.
const selectedValue = this.state.firstCompanyName;
console.log('change value',selectedValue)`
Related
I am migrating my code from Class-Based Components to Function-Based Components. My code runs fine in Class-Based Component, however when I modified the code to Function-Based Components, I am getting TypeError: Cannot read property 'props' of undefined. My Class-Based Component Code is as follows :
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { InputData } from '../store/action/action.js';
class FirstPage extends Component {
constructor() {
super();
this.state = {
inputState: ''
}
}
getInputText() {
var text = document.getElementById('inputText').value;
this.setState({ inputState: text });
this.props.inputData(text);
}
render() {
const { inputState } = this.state;
return (
<div>
<p>Type Something</p>
<input id="inputText" type="text"></input>
<button style={{ marginLeft: '10px' }} onClick={() =>
this.getInputText()}>Submit</button>
<p>You Wrote : {inputState}</p>
<br /><br />
<Link to="/second"><button>Go to Second Page</button></Link>
</div>
);
}
}
function mapStateToProp(state) {
return ({
// Get data from store
})
}
function mapDispatchToProp(dispatch) {
return ({
// Send data to store
inputData: (data) => { dispatch(InputData(data)) }
})
}
export default connect(mapStateToProp, mapDispatchToProp)(FirstPage);
My Function-Based Component Code is as follows :
import { useState } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { InputData } from '../store/action/action.js';
const FirstPage = () => {
const [inputState, setInputState] = useState('');
const getInputText = () => {
var text = document.getElementById('inputText').value;
setInputState(text);
this.props.inputData(text); // **** THE ERROR IS APPEARING BECAUSE OF THIS LINE ****
}
return (
<div>
<p>Type Something</p>
<input id="inputText" type="text"></input>
<button style={{ marginLeft: '10px' }} onClick={getInputText}>Submit</button>
<p>You Wrote : {inputState}</p>
<br /><br />
<Link to="/second"><button>Go to Second Page</button></Link>
</div>
);
}
function mapStateToProp(state) {
return ({
// Get Data from Store
})
}
function mapDispatchToProp(dispatch) {
return ({
// Send data to Store
inputData: (data) => { dispatch(InputData(data)) }
})
}
export default connect(mapStateToProp, mapDispatchToProp)(FirstPage);
There's no this in functional component
const FirstPage = ({ inputData }) => {
const [inputState, setInputState] = useState('');
const getInputText = () => {
var text = document.getElementById('inputText').value;
setInputState(text);
inputData(text); // <-- Look here
}
In function components props is passed in as a parameter. Pass props as a parameter to component and when referencing props, use props. rather than this.props
import { useState } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { InputData } from '../store/action/action.js';
const FirstPage = props => {
const [inputState, setInputState] = useState('');
const getInputText = () => {
var text = document.getElementById('inputText').value;
setInputState(text);
props.inputData(text);
}
return (
<div>
<p>Type Something</p>
<input id="inputText" type="text"></input>
<button style={{ marginLeft: '10px' }} onClick={getInputText}>Submit</button>
<p>You Wrote : {inputState}</p>
<br /><br />
<Link to="/second"><button>Go to Second Page</button></Link>
</div>
);
}
function mapStateToProp(state) {
return ({
// Get Data from Store
})
}
function mapDispatchToProp(dispatch) {
return ({
// Send data to Store
inputData: (data) => { dispatch(InputData(data)) }
})
}
export default connect(mapStateToProp, mapDispatchToProp)(FirstPage);
I have been building a trivia game using the Open Trivia API and I am getting an error that I have been trying to figure out but am stuck on. It says: Invalid value for prop value on tag. Either remove it from the element, or pass a string or number value to keep it in the DOM.
I will include my code pages. Thank you in advance for you help.
App.js page:
import React from 'react'
import './App.css'
import axios from 'axios'
import Questions from './components/questions'
import CategorySelector from './components/CategorySelector'
class App extends React.Component {
constructor () {
super()
this.state = {
categories: [],
selectedCategory: null
}
this.selectedCategory = this.selectedCategory.bind(this)
}
componentDidMount () {
axios
.get('https://opentdb.com/api_category.php')
.then(response => {
console.log(response.data)
this.setState({
categories: response.data.trivia_categories
})
})
}
selectedCategory (category) {
this.setState({ selectedCategory: category })
}
render () {
const { categories, selectedCategory } = this.state
return (
<div className='App'>
<h2>Trivia Game</h2>
{
selectedCategory
? <Questions selectedCategory={selectedCategory} />
: (
<CategorySelector
categories={categories}
onSelect={event => selectedCategory}
selectedCategory={this.selectedCategory}
/>
)
}
</div>
)
}
}
export default App
CategorySelector.js page:
import React from 'react'
class CategorySelector extends React.Component {
render () {
const { categories, selectedCategory, onSelect } = this.props
return (
<div className='CategorySelector'>
<select
value={selectedCategory} onChange={onSelect}
>
<option value=''>-- No category selected --</option>
{categories.map(category => (
<option value={selectedCategory} key={category.id}>{category.name}</option>
))}
</select>
</div>
)
}
}
export default CategorySelector
Question.js page
import React from 'react'
import axios from 'axios'
class Questions extends React.Component {
constructor () {
super()
this.state = {
questions: [],
currentQuestionIndex: 0
}
this.handleNextQuestion = this.handleNextQuestion.bind(this)
}
componentDidMount () {
const qUrl = `https://opentdb.com/api.php?amount=3&category=${this.props.selectedCategory.id}`
axios
.get(qUrl)
.then(response => {
console.log(response.data)
this.setState({
questions: response.data.results
})
})
}
handleNextQuestion () {
this.setState({ currentQuestionIndex: this.state.currentQuestionIndex + 1 })
}
render () {
const { selectedCategory } = this.props
const { questions, currentQuestionIndex } = this.state
const currentQuestion = questions[currentQuestionIndex]
let answers = []
if (currentQuestion) {
answers = currentQuestion.incorrect_answers.concat([currentQuestion.correct_answer])
}
return (
<div className='Questions'>
<h2>{selectedCategory.name} Questions</h2>
{currentQuestion && (
<div>
<h3>{currentQuestion.questions}</h3>
<div>
{answers.map((answer, index) => <p key={index}>{answer}</p>)}
</div>
</div>
)}
{(currentQuestionIndex < questions.length - 1) &&
<button onClick={this.handleNextQuestion}>Next Question</button>}
</div>
)
}
}
export default Questions
While passing the prop, you're referring the state variable as this.selectedCategory
Change this line
selectedCategory={this.selectedCategory}
to
selectedCategory={selectedCategory}
The program flows as follows:
Home.js => Add.js => Detail.js => Repeat...
Home.js lists the posts.
Add.js is a page for entering the data required for a post. Move through stack navigation from Home.js
Detail.js will take over the data entered in Add.js as a parameter, show you the information of the post to be completed, and press the Done button to move to Home.js.
Home.js contains posts that have been completed.
If a post is created, eatObject is assigned an object from Detail.js.
Const { eatObject } = this.props.route?params || {};
In Home.js, state has an array of objects toEats.
Add eatObject to the object list
{Object.values(toEats).map(toEat =toEat.id toEat.idToEat key={toEat.id} {...toEat} deleteToEat={this._deleteToEat} />)}
Currently, the refresh button updates the 'Home.js' list whenever a post is added. But I want the list of posts to be updated automatically whenever 'Home.js' is uploaded.
I tried to call '_pushToEat' in 'componentDidMount', but 'eatObject' exists in 'render' so it seems impossible to hand it over to parameters.
I want to automatically call '_pushTooEat' when the components of 'Home.js' are uploaded.
Home.js
import React from "react";
import { View, Text, Button } from "react-native";
import ToEat from "./ToEat"
export default class Home extends React.Component {
state = {
toEats:{}
}
render() {
const { toEats } = this.state;
const { eatObject } = this.props.route?.params || {};
// error
// if (eatObject) {
// () => this._pushToEat(eatObject)
// }
return (
<View>
{Object.values(toEats).map(toEat => <ToEat key={toEat.id} {...toEat} deleteToEat={this._deleteToEat} />)}
<Button title="refresh" onPress={()=>this._pushToEat(eatObject)}/>
<View>
<Button title="Add" onPress={() => this.props.navigation.navigate("Add")} />
</View>
</View>
);
}
_deleteToEat = () => {
}
_pushToEat = (eatObject) => {
console.log("function call!")
console.log(eatObject)
this.setState(prevState => {
const newToEatObject = eatObject
const newState = {
...prevState,
toEats: {
...prevState.toEats,
...newToEatObject
}
}
return { ...newState };
})
}
}
Detail.js
import React from "react";
import { View, Text, Button } from "react-native";
import uuid from 'react-uuid'
import { connect } from 'react-redux';
import { inputId } from '../src/reducers/infoReducer';
class Detail extends React.Component {
render() {
const { name, dosage, note } = this.props.route.params;
return (
<View>
<Text>name: {name}</Text>
<Text>dosage: {dosage}</Text>
<Text>note: {note}</Text>
<Button
title="Done"
onPress={() =>
this.props.navigation.navigate(
"Home", {
eatObject: this._createToEat(uuid(), name, dosage)
})
}
/>
</View>
)
}
_createToEat = (id, name, dosage) => {
const ID = id
inputId(id)
const newToEatObject = {
[ID]: {
id: ID,
name: name,
dosage: dosage,
}
}
return newToEatObject;
}
}
function mapStateToProps(state) {
return {
state: state.infoReducer
};
}
function matchDispatchToProps(dispatch) {
return {
inputId: (id) => {
dispatch(inputId(id));
},
}
}
export default connect(mapStateToProps, matchDispatchToProps)(Detail);
I want your advice.
Thank you
I'm building a help page with Gatsby and have a search bar (Searchbar.js) where I'm trying to pass the user's input in the field (search bar is always present within the page--think like Evernote's help page) to a component that conducts the search (search.js), which then passes that output to the actual results page (SearchResults.js).
When I do gatsby develop everything works as it should, but when I do a gatsby build I get an error where it says it cant read the property "query" because its undefined (line 63 of search.js: var search = location.state.query.trim()). Why is this failing on build?
Searchbar.js
import React from 'react'
import { navigate } from 'gatsby'
import { FaSearch } from 'react-icons/fa'
import searchbarStyles from "./searchbar.module.css"
export default class Search extends React.Component {
constructor(props) {
super(props)
this.state = {
search: ''
}
this.handleSubmit = this.handleSubmit.bind(this)
this.handleChange = this.handleChange.bind(this)
}
handleSubmit(event) {
event.preventDefault()
var query = this.state.search
navigate(
"/search/",
{
state: { query },
}
)
}
handleChange(event) {
this.setState({
search: event.target.value
})
}
render(){
return (
<div className={searchbarStyles.global_search}>
<div className={searchbarStyles.row}>
<form className={searchbarStyles.search} onSubmit={this.handleSubmit}>
<input
type='text'
id='globalSearchInput'
className=''
placeholder='Search Help & Training'
autoComplete='off'
value={this.state.search}
onChange={this.handleChange}
/>
<button
type='submit'
disabled={!this.state.search}
><FaSearch className={searchbarStyles.searchIcon}/></button>
</form>
</div>
</div>
)
}
}
search.js
import React, { useMemo } from 'react'
import Layout from '../components/Layout'
import SearchResults from '../components/SearchResults'
import { graphql } from 'gatsby'
import Fuse from 'fuse.js'
const matchThreshold = .65
//options for the fuzzy search
var fuseOptions = {
shouldSort: true,
threshold: matchThreshold,
location: 0,
distance: 99999999999,
minMatchCharLength: 1,
includeMatches: true,
includeScore: true,
keys: [
{name: "title", weight: 0.3 },
{name: "content", weight: 0.7}
]
};
function cleanString(string) {
const re = /( |<([^>]+)>)/ig
return string.replace(re,'')
}
function FuzzySearch (query, data) {
fuseOptions.minMatchCharLength = query.length
var dataPrepped = data.map(function(element) {
return {
"title": element.node.frontmatter.title,
"content": cleanString(element.node.html),
"slug": element.node.fields.slug,
}
})
var fuse = useMemo(() => new Fuse(dataPrepped, fuseOptions), [])
var results = fuse.search(query)
//customize the results to only return matches within desired threshold
return results.filter(function(match) {
if(match.score <= matchThreshold) {
return true
}
return false
}).map(function(match) {
return {
"title": match.item.title,
"slug": match.item.slug,
"matches": match.matches
}
})
}
export default ({ location, data }) => {
console.log("SERACH.JS\n")
console.log(JSON.stringify(location))
var search = location.state.query.trim()
var results = []
if(search.length) results = FuzzySearch(search, data.allMarkdownRemark.edges)
return (
<Layout>
<SearchResults FoundItems={results} SearchedTerm={search}> </SearchResults>
</Layout>
)
}
export const query = graphql `
query MyQuery {
allMarkdownRemark {
edges {
node {
fields {
slug
}
frontmatter {
title
date
doctype
}
html
}
}
}
}
`
SearchResults.js
import React from 'react'
import { Link } from 'gatsby'
import searchResultStyles from "./searchresults.module.css"
function resultsPage(resultsBlurb, results) {
return(
<div className={searchResultStyles.content}>
<h1>Search Results</h1>
<p className={searchResultStyles.resultBlurb}>{resultsBlurb}</p>
<ol>
{results.map((match) => (
<li>
<div className={searchResultStyles.resultContent}>
<Link to={match.slug} className={searchResultStyles.resultTitle}>{match.title}</Link>
{match.matches.map(function(instanceOfMatch) {
if(instanceOfMatch.key === "content") {
let startIndex = instanceOfMatch.indices[0][0]
return(
<p className={searchResultStyles.resultExcerpt}>{`...${instanceOfMatch.value.substring(startIndex, startIndex + 100)}...`}</p>
)
}
})}
</div>
</li>
))}
</ol>
</div>
)
}
class SearchResults extends React.Component {
constructor(props) {
super(props)
this.state = {
results: props.FoundItems,
term: props.SearchedTerm,
}
this.updateBlurb = this.updateBlurb.bind(this)
}
updateBlurb() {
let resultsBlurb = `Sorry--could not find any results for "${this.state.term}"`
if (this.state.results.length) {
resultsBlurb = (this.state.results.length === 1) ? `Only 1 item found for "${this.state.term}"` : `Found ${this.state.results.length} items for "${this.state.term}"`
}
return resultsBlurb
}
componentDidUpdate(prevProps) {
if(prevProps!== this.props) {
this.setState ({
results: this.props.FoundItems,
term: this.props.SearchedTerm
})
}
return(resultsPage(this.updateBlurb(), this.props.FoundItems))
}
render() {
return(resultsPage(this.updateBlurb(), this.state.results))
}
}
export default SearchResults
SOLUTION
(within search.js)
export default ({ location, data }) => {
var search = ''
var results = []
if(typeof window !== "undefiend") search = location.state.query.trim()
if(search.length) results = ...
location is short for window.location, but at build-time your code is running in Node.js which does not have a window. Instead consider testing for the existence of window (typeof window !== "undefined") before running your location.state.query.trim call, and fall back to a default value in the case that window does not exist.
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} />
));
}