Recently I started practicing React.
I'm trying to create a simple app that would count how many kg of plastic do we use, according on how many bottles of water we use every day.
Using this info, I want to show what could be produced out of recycled plastic that we use per year.
So I have a component Calculator:
class Calculator extends React.Component {
constructor(props) {
super(props);
this.state = {
resultNumber: null,
resultKg: null
}
}
count = (e) => {
let val = e.target.value;
let resultNumber = val * 52;
let resultKg = Math.round(resultNumber * 0.04);
this.setState({
resultNumber: resultNumber,
resultKg: resultKg
})
}
render() {
return ( <div >
<Menu / >
<div className = "component" >
<h1 > I use < input type = "text" className = "input-data" onChange = {this.count}/> bottles per week</h1 >
<div className = "resultInfo" > {this.state.resultNumber != null ?
<Info resultNumber = {this.state.resultNumber}
resultKg = { this.state.resultKg } /> :null} < /div>
</div>
</div>
)
}
}
I have a component that shows the result:
const Info = (props) => {
return(
<div>
<div className="info">
<div><p>{props.resultNumber} bottles per year</p>
<img src={bottle1} />
</div>
<div><p>{props.resultKg} kg of plastic per year</p>
<img src={trash} />
</div>
</div>
<p>What could be produced out of {props.resultKg} kg of plastic?</p>
</div>
)
}
The problem is that I don't know how to get the {props.resultKg} in another component that renders what could be produced:
const Recycle = (props) => {
return({props.resultKg})
}
The last component, of course, returns "undefined".
I tried to learn Redux but it became overwhelming and I got even more confused. Could you help me to understand how I can get state from Calculator in my Recycle component?
In the end I had to learn Redux to make it. :)
Related
**I have a code that displays the news of the day. https://ibb.co/QMLY2Kx I have 10 classes named "block". Inside the "block" class there are two classes named "blockText". I need to get two different class names and not the same, I want to get this result "blockText1" and "blockText2". How to do it? **
import React from 'react';
import newsStyle from './News_module.css';
export class News extends React.Component {
render() {
const resultsRender = [];
for (var i = 0; i < this.props.news.length; i += 2) {
resultsRender.push(
<div class="block">
{
this.props.news.slice(i, i + 2).map((news, index) => {
return (
<div class="blockText" key={index}>
<p class="text">{news.title}</p>
{console.log(this.props.news.length)}
</div>
);
}
)
}
</div>
);
}
return (
<div>
<div className="headlineSecond">
<div className="Second">
{resultsRender}
</div>
</div>
</div>
);
}
}
You can use ternary operator for this . Here is an example where i chose the value of class based on the value of index and deciding upon whether it is even or odd
<div class={ index%2 ===0 ? "blockText1": "blockText2" } key={index}>
..... rest of code
</div>
This question already has answers here:
Correct modification of state arrays in React.js
(19 answers)
Closed 3 years ago.
I am trying to build a React app where i can input my weight and height and it will count value of my BMI and show it on a diagram. I did not want to make everything in one component so i divided it into small components.
Here is the main App Component:
const App_function = () => {
const [arrayBMI, setArrayBMI]=useState([]);
const [dateArray, setDateArray]=useState([]);
const handlerMain = (heightData, weightData) => {
const valueOfBMI = weightData / (heightData/100*heightData/100);
console.log(valueOfBMI);
const repMainArray = arrayBMI;
repMainArray.push(valueOfBMI);
setArrayBMI(repMainArray);
const repDateArray = dateArray;
let currentDateData = new Date();
let day = currentDateData.getDate();
if(day < 10) {
day = '0' + day;
}
let month = currentDateData.getMonth() + 1;
if(month < 10) {
month = '0' + month;
}
let year = currentDateData.getFullYear();
let date = `${day}-${month}-${year}`;
repDateArray.push(date);
setDateArray(repDateArray);
}
return (
<div>
<Data handlerFunction={handlerMain}/>
<Diagram arrayMain={arrayBMI} arrayOfDate={dateArray}/>
<div>{arrayBMI[0]} a {arrayBMI[1]}</div>
<StoragE/>
</div>
);
}
And here is the Data Component:
function data_function(props) {
function formCloser(event) {
event.preventDefault();
let heightField = event.target.querySelector('#height').value;
let weightField = event.target.querySelector('#weight').value;
props.handlerFunction(heightField, weightField);
event.target.querySelector('#height').value='';
event.target.querySelector('#weight').value='';
}
return (
<div className="main-div">
<p className="paragraph-boy">BMI Calculator</p>
<form onSubmit={formCloser}>
<div className="inputs">
<div className="input_fields">
<label htmlFor="weight">Weight (in kg)</label>
<input type="text" id="weight" placeholder="50" autoComplete="off"></input>
</div>
<div className="input_fields">
<label htmlFor="height">Height (in cm)</label>
<input type="text" id="height" placeholder="175" autoComplete="off"></input>
</div>
</div>
<button type="submit" className="btn">Calculate BMI</button>
</form>
</div>
);
}
export default data_function;
As you can see App Component is the parent of Data Component. Whenever I fill out the form and hit submit, it triggers handlerFunction which passes the data from
the Data Component to the App Component. The data which was sent to App Component is used to calculate the BMI and then the value of it is pushed into arrayBMI (which is a state in App Component). I don't understand why after submitting it does not re-render the App Component.
Last 2 days i was probably trying to fix the problem which was caused by it. Today i discovered that my main App Component does not re-render when the value of any of the state changes and i have not idea why.
Replace this code
const repMainArray = arrayBMI;
repMainArray.push(valueOfBMI);
by
const repMainArray = [...this.sate.arrayBMI,valueOfBMI] ;
and
const repDateArray.push(date);
Wrap your main handler function in https://reactjs.org/docs/hooks-reference.html#usecallback to have dependencies (listeners for changes).
Hello I am new to React and building a quote generator. I want to pull out one quote at a time from my array and show it on the screen, however I can only seem to output each quote to the console.
I have:
1.Created an on click handler and function so that when the user clicks my quote array is targeted.
2. In this function I have created a variable to hold my random array index
3. I have console.logged the array index to see if every time the user clicks it the quote appears.
Component and function and click handler, as you can see the Quote Component should return the quote from the array in my opinion but nothing happens:
class Card extends Component {
state = {
quotes: ['"A dream doesn\'t become reality through magic; it takes sweat, determination and hard work."','"You GOT this!"','"To be or not to be that is the question"'];
changeQuoteHandler = (event) => {
const quotes = [...this.state.quotes];
const arrayIndex = quotes[Math.floor(Math.random() * quotes.length)]
console.log(arrayIndex);
this.setState({
quotes: quotes
})
};
render(){
return (
<div className="Card">
<div>
<h2>Random Quote Generator</h2>
<Quote className="QuoteStyle" quote={this.state.quotes.arrayIndex}/>
</div>
<div className="Flex">
<div>
<NewQuoteButton onClick={this.changeQuoteHandler}/>
</div>
</div>
</div>
)
}
};
export default Card;
Quote Componenet :
import React from 'react';
const Quote = (props) => {
return(
<p>{props.quote}</p>
)
};
export default Quot
I would like to print one quote at a time to the screen on click.
You are so close. You can store the arrayIndex that you generate in the state and use it to display the quote. The code would look like something below
class Card extends Component {
state = {
quotes: ['"A dream doesn\'t become reality through magic; it takes sweat, determination and hard work."','"You GOT this!"','"To be or not to be that is the question"'],
selectedIndex: 0,
}
changeQuoteHandler = (event) => {
const quotes = [...this.state.quotes];
const arrayIndex = Math.floor((Math.random() * 10) % quotes.length);
this.setState({
quotes: quotes,
selectedIndex: arrayIndex,
});
};
render(){
return (
<div className="Card">
<div>
<h2>Random Quote Generator</h2>
<Quote className="QuoteStyle" quote={this.state.quotes[this.state.selectedIndex]}/>
</div>
<div className="Flex">
<div>
<NewQuoteButton onClick={this.changeQuoteHandler}/>
</div>
</div>
</div>
)
}
};
export default Card;
I have a code, i did want to render the first three. elements of a array with several elements.
How i do can do that ?
My code:
function AllComponnent () {
const arr = [1,2,3,4];
const elementsPerPage = 3;
const currentPage = 0;
const itensOnPage = arr.map(() => <ul> {currentPage*elementsPerPage} </ul>
);
return (
<div>
<input/>
<button onClick={action}> Click Here </button>
<button onClick={action}> Test</button>
<h1> {itensOnPage} </h1>
</div>
)}
ReactDOM.render (
<AllComponnent/>,
document.getElementById('root'))
<div id="root"></div>
You'd probably want to try something like
<h1>
{
itemsOnPage.slice(
currentPage * elementsToRender,
(currentPage + 1) * elementsToRender
)
}
</h1>
Though it'd be best to utilize React state here. If you had a constructor in your component, what you could do is
constructor(props) {
this.state = { currentPage: 0, elementsPerPage: 3 }
this.itemsToRender = [...]
}
renderableItems() {
return this.itemsToRender.slice(
this.state.currentPage * this.state.elementsPerPage,
(this.state.currentPage + 1) * this.state.elementsPerPage
)
}
render() {
return (
<div>
{
//... other HTML
}
<h1>{ this.renderableItems() }</h1>
</div>
)
}
There are great resources to learn JSX from the guys that wrote React itself, like https://reactjs.org/docs/introducing-jsx.html.
You can use slice
const itensOnPage = arr.slice(0, elementsPerPage)map(() => // do your logic );
Hope this works.
I'm fairly new to ReactJS. I am looking to get the value inside a <div> when contentEditable is set to true.
const listResults = this.state.results['1'].map((result) =>
<div key={result.toString()} contentEditable="true">
{result}
</div>
);
return (
<h1> listResults </h1>
<div> {listResults} </div>
)
I am currently outputting a list into pre-filled text-boxes which allows the user to edit them. I am looking to add in a button which once clicked captures the data inside all of the text-boxes. Can anyone point me in a direction on how to capture the changed data.
It may also be worth noting I am using ReactJS on the client side through a CDN.
To get value of editable div:
class App extends React.Component {
constructor(){
super();
this.state = {
arr: [1,2,3,4,5]
}
this.change = this.change.bind(this);
}
change(e, index){
let tmpArr = this.state.arr;
tmpArr[index] = e.target.textContent;
this.setState({arr: tmpArr})
}
render(){
console.log(this.state);
return (
<tr>
{this.state.arr.map((el, index) => <td key={index} id="test" onBlur={(e) => this.change(e, index)} contentEditable="true">{el}</td>)}
</tr>
);
}
}
https://jsfiddle.net/69z2wepo/84647/
One note, you can't return two elements on the same level:
return (
<h1> listResults </h1>
<div> {listResults} </div>
)
It should be wrapped like this:
return (
<div>
<h1> listResults </h1>
<div> {listResults} </div>
</div>
)