I am trying to generate random number for test functionality to display in my Material UI Progress bar . This piece of JS code is working in JS fiddle.
But I want to show this random number with my reactJs.
Any help/suggestion how can I achieve this.
//Testcode
class TestPage extends React.Component {
constructor(props) {
super(props);
this.state = {
displayProgress: ""
}
}
displayProgress() {
this.setState(document.getElementById('out').innerHTML = Math.random() * 101 | 0);
}
render() {
const { displayProgress } = this.props;
const createProgress = setInterval(displayProgress, 1000);
return (
<div className="test">
<div id="out"></div>
<LinearProgress variant="determinate" value={createProgress} />
</div>
);
}
};
export default TestPage;
Accessing dom elements directly is not a good idea in react. this makes more sense:
class TestPage extends React.Component {
constructor(props) {
super(props);
this.state = {
progress : 0
}
}
componentDidMount(){
this.interval = setInterval(()=>{
this.displayProgress();
},1000)
}
componentWillUnmount(){
clearInterval(this.interval);
}
displayProgress = () => {
const prog = Math.random() * 101
this.setState({
progress : prog
})
}
render() {
return (
<div className="test">
<LinearProgress variant="determinate" value={this.state.progress} />
</div>
);
}
};
export default TestPage;
this should do it.
I am trying to generate inputs on a button click and the amount of inputs is generated by a random number. Here is what I have so far, but it isn't working. I am very confused and feel like it should be working. I am not sure what I am missing. Any help would be very much appreciated.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { Image } from './Image.js'
import { Button } from './Button.js'
import { images } from './assets/images.js'
import { Countdown } from './Countdown.js'
import { DisplayCount } from './DisplayCount.js'
import { Inputs } from './Inputs.js'
class Game extends React.Component{
constructor(props){
super(props)
this.timer = null
this.state = {
currentImg: 0,
timer: null,
ranNum: null
}
this.handleClick = this.handleClick.bind(this)
}
countdownClock = async (newRanNum) => {
const startingNum = newRanNum * 20;
for(let i = startingNum; i >= 0; i--) {
await new Promise(resolve => {
this.timer = setTimeout(() => {
this.setState({
timer: i
})
resolve()
}, 1000)
});
}
}
generateInputs = (newRanNum) => {
const inputs = []
for(let i = 1; i <= newRanNum; i++){
inputs.push(
<Inputs type='text' className='textInputs' />
)
}
return inputs;
}
handleClick(){
clearTimeout(this.timer)
let newRanNum = Math.floor(Math.random() * 20);
this.countdownClock(newRanNum)
this.generateInputs(newRanNum)
let current = this.state.currentImg;
let next = ++current % images.length;
this.setState({
currentImg: next,
ranNum: newRanNum
})
}
render(){
let src = this.state.currentImg;
return(
<div>
<Countdown name={'Countdown: '} countdown={this.state.timer} />
<DisplayCount name='Word Count: ' count={this.state.ranNum} />
<Image src={images[src]} />
<Button onClick={this.handleClick} />
<div>
<ul>
{this.generateInputs()}
</ul>
</div>
</div>
)
}
}
ReactDOM.render(
<Game />,
document.getElementById('root')
);
Inputs component:
import React from 'react'
export const Inputs = (props) => {
return (
<li className={props.className}>
<input value={props.value} />
</li>
)
}
I believe the issue is here...
generateInputs = (newRanNum) ...
and here...
{this.generateInputs()}
You're input rendering function is expecting a parameter it's not getting, and since that returns as undefined the loop never runs. :)
In general, it is most common to separate state (eg, number of inputs) from the rendering, and only have the rendering respond to state. Perhaps you had originally intended generateInputs() to produce the array, and not render them (?)
The first thing is your generateInputs() function takes a parameter for number of inputs you wanted to render but you are not passing any parameter to this.generateInputs()
The second thing is you are returning an array from this function but not mapping your array in the render function, So do in this way.
this.generateInputs(10) // pass parameter here
this.generateInputs(10).map((item, index)=>item)
In this Snack, I have done the same thing but with react-native
https://snack.expo.io/#waheed25/smiling-carrot
New to react cannot access state. Can someone explain?
I am trying to create bar graphs on the board and then whenever the button is clicked I want to perform one iteration of a sorting algorithm. I need the logic for: whenever the button is clicked, then I want to re render the squares based on their heights.Can someone push me in the right direction?
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
heightSet: 3,
};
}
render() {
var divHeightStyle = {
height: this.props.heightSet + 'em',
};
return (
<button
id={this.props.value}
value={this.props.heightSet}
style={divHeightStyle}
className="square">
{this.props.value}
</button>
);
}
}
class Rectangle extends React.Component {
constructor(props){
super(props);
};
reccheck = () => {
this.props.check();
}
render(){
return (
<button
className="rectangle"
onClick={() => this.reccheck()} >
</button>
)
}
}
class Board extends React.Component {
constructor(props) {
super(props);
const min = 1;
const max = 80;
const rand = min + Math.random() * (max - min)
const rand1 = min + Math.random() * (max - min)
const rand2 = min + Math.random() * (max - min)
const rand3 = min + Math.random() * (max - min)
this.state = {
squares: [rand, rand1, rand2, rand3],
};
}
renderSquare(i, y) {
return <Square value={i} heightSet={y}/>;
}
check(){
if(this.state.squares[0] > this.state.squares[1]) {
alert('0 is bigger');
}
}
renderRectangle() {
return <Rectangle check={this.check}/>;
}
render() {
const status = '';
return (
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(1,this.state.squares[0])}
{this.renderSquare(2,this.state.squares[1])}
{this.renderSquare(3,this.state.squares[2])}
{this.renderSquare(4,this.state.squares[3])}
</div>
{this.renderRectangle()}
</div>
);
}
}
class Game extends React.Component {
render() {
return (
<div className="game">
<div className="game-board">
<Board />
</div>
<div className="game-info">
<div>{/* status */}</div>
<ol>{/* TODO */}</ol>
</div>
</div>
);
}
}
// ========================================
ReactDOM.render(
<Game />,
document.getElementById('root')
);
When you call to a function like you are doing, you are using a different this. You should either bind the correct this or use an arrow function.
Binding:
renderRectangle() {
return <Rectangle check={this.check.bind(this)}/>;
}
or, arrow function:
check: () => {
if(this.state.squares[0] > this.state.squares[1]) {
alert('0 is bigger');
}
Basically, I am trying to make a card program that would pick five cards out of 52 in random. These cards must not repeat. I have already figured out the randomizer through traditional javascript. However, I am using ReactJs to make a button which if pressed, would create a new set of five cards.
class Reset extends React.Component {
constructor(props) {
super(props);
this.state = {...};
}
handleClick() {...}
render() {
return <button onClick={this.handleClick}>{...}</button>;
}
}
const cards = [
"A♥",
"A♠",
"A♦",
"A♣",
"2♣",
"3♣",
"4♣",
"5♣",
"6♣",
"7♣",
"8♣",
"9♣",
"10♣",
"K♣",
"Q♣",
"J♣",
"2♦",
"3♦",
"4♦",
"5♦",
"6♦",
"7♦",
"8♦",
"9♦",
"10♦",
"K♦",
"Q♦",
"J♦",
"2♥",
"3♥",
"4♥",
"5♥",
"6♥",
"7♥",
"8♥",
"9♥",
"10♥",
"K♥",
"Q♥",
"J♥",
"2♠",
"3♠",
"4♠",
"5♠",
"6♠",
"7♠",
"8♠",
"9♠",
"10♠",
"K♠",
"Q♠",
"J♠"
];
var hand = [];
function in_array(array, el) {
for (var i = 0; i < array.length; i++) if (array[i] == el) return true;
return false;
}
function get_rand(array) {
var rand = array[Math.floor(Math.random() * array.length)];
if (!in_array(hand, rand)) {
hand.push(rand);
return rand;
}
return get_rand(array);
}
for (var i = 0; i < 5; i++) {
document.write(get_rand(cards));
}
ReactDOM.render(<Reset />, document.getElementById("root"));
Basically, what would I have to fill in the parts with "..." in order for the code to rerandomize the pack.
Try something like this, I'm preserving alot of the code you already wrote. You really just have to move that logic into the handler.
Here's the sandbox as well: https://codesandbox.io/s/yv93w19pkz
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
cards: ["A♥", "A♠", "A♦", "A♣", "2♣", "3♣", "4♣", "5♣", "6♣", "7♣", "8♣", "9♣", "10♣", "K♣", "Q♣", "J♣", "2♦", "3♦", "4♦", "5♦", "6♦", "7♦", "8♦", "9♦", "10♦", "K♦", "Q♦", "J♦", "2♥", "3♥", "4♥", "5♥", "6♥", "7♥", "8♥", "9♥", "10♥", "K♥", "Q♥", "J♥", "2♠", "3♠", "4♠", "5♠", "6♠", "7♠", "8♠", "9♠", "10♠", "K♠", "Q♠", "J♠"],
hand: []
}
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
const cards = this.state.cards
const newHand = []
function get_rand(array) {
var rand = array[Math.floor(Math.random() * array.length)];
if (!newHand.includes(rand)) {
newHand.push(rand);
} else {
get_rand(cards);
}
}
for (var i = 0; i < 5; i++) {
get_rand(cards);
}
this.setState({
hand: newHand
})
}
render() {
const { hand } = this.state
return (
<div>
{ hand ? (hand.map((card) => {
return <p>{card}</p>
})) : (
null
)}
<button onClick={this.handleClick}>Randomize
</button>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
Try to declare the cards in the state and update when you click on it
New to ReactJS.
I'm attempting to build a little component that moves some components around a container. The idea is that the user clicks on a button and the divs position changes.
I've tried to use Object.keys and Object.entries neither of them worked. I tried to create an array out of this.state so that I could just do array.map() but it did not work.
constructor(props) {
super(props);
this.handleShuffle = this.handleShuffle.bind(this);
this.state = {
redLeft: 0,
redTop: 0,
blueLeft: 0,
blueTop: 70
}
}
getRandomNumber (min, max) {
return min + (Math.floor(Math.random() * (max-min)))
}
handleShuffle() {
const min = 0;
const max = 230;
this.setState({
redLeft: this.getRandomNumber(min, max),
redTop: this.getRandomNumber(min, max),
blueLeft: this.getRandomNumber(min, max),
blueTop: this.getRandomNumber(min, max),
});
}
The code above is as far as I got, it works but surely there is a way to loop over the different properties in this.state and call the function for each item?
You could use reduce if your state only ever includes keys you want to apply the random number to:
this.setState((prevState) => (Object
.keys({...prevState})
.reduce((newState, next) => {
newState[next] = this.getRandomNumber(min, max);
return newState;
}, {})));
Not sure why Object.keys doesn't work for you but it does actually work. Here, I loop over the keys of this.state and set the state for that key.
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = {
redLeft: 0,
redTop: 0,
blueLeft: 0,
blueTop: 70
}
}
componentDidMount () {
this.handleShuffle()
}
getRandomNumber (min, max) {
return min + (Math.floor(Math.random() * (max-min)))
}
handleShuffle() {
const min = 0;
const max = 230;
Object.keys(this.state).map(k => {
this.setState({
[k]: this.getRandomNumber(min, max)
})
})
}
render () {
return JSON.stringify(this.state)
}
}
ReactDOM.render(<Foo />, document.getElementById('foo'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="foo"></div>