I'm trying to learn React and am working on a simple web app to implement what I've learned online so far.
I have a container called CardDatabase.js
and all it returns is a single value. This value is called reduceArray
and it's an array that has had the reduce()
method called on it. When I render <CardDatabase.js />
the value appears in the browser and in the console as intended (in the screenshot, it's 86). However, when I try to assign the value of <CardDatabase />
to variable w
inside of the calculate
method in App.js
, an object is returned instead of a numeric value (check the console in the screenshot).
How can I assign the numeric value of <CardDatabase />
to a variable so that I can use it to calculate some simple math?
I also tried using props and this.state
but according to the console error I got and the React docs, we cannot modify the value of props? So when I tried something like:
const array = (rarityOfArray) => {
filteredArray = rarityOfArray.filter(item => item.key <= level)
for(let x = 0; x < filteredArray.length; x++) {
pushedArray.push(filteredArray[x].cardsRequiredToUpgrade)
console.log(pushedArray);
}
props.array = pushedArray.reduce((a, b) => a + b, 0);
console.log("Reduced - " + reducedArray);
return props.array
}
I got this error message: TypeError: Cannot assign to read only property 'array' of object '#<Object>'
Any help or direction would be greatly appreciated.
App.js
import React, {Component} from 'react';
// CSS
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
// Components
import CardRarityDropdown from './components/CardRarityDropdown';
import CardLevelDropdown from './components/CardLevelDropdown';
import CardAmountInput from './components/CardAmountInput';
import CardCalculationsButton from './components/CardCalculationsButton';
//Containers
import CardDatabase from './containers/cardDatabase/CardDatabase';
class App extends Component {
constructor() {
super();
this.state = {
cardRarity: "",
cardLevel: "",
amountOfCards: "",
}
this.setCardValues = this.setCardValues.bind(this);
}
setCardValues = (event) => {
const {name, value} = event.target
this.setState({
[name]: value
})
}
calculate = () => {
let v = this.state.cardRarity;
console.log("v: " + v)
let w = <CardDatabase />
console.log("w: " + w)
let x = v - w;
console.log("x: " + x)
let y = this.state.amountOfCards;
console.log("y: " + y)
let z = x - y;
console.log("z: " + z)
return z
}
render () {
return (
<div>
<h1 id="superCellText">Clash Royale Card Calculator</h1>
<CardRarityDropdown
setCardValues={this.setCardValues}
cardRarity={this.state.cardRarity} />
<CardLevelDropdown
setCardValues={this.setCardValues}
cardRarity={this.state.cardRarity}
cardLevel={this.state.cardLevel} />
<CardDatabase
cardRarity={this.state.cardRarity}
cardLevel={this.state.cardLevel} />
<CardAmountInput
setCardValues={this.setCardValues}
cardRarity={this.state.cardRarity}
amountOfCards={this.state.amountOfCards} />
<CardCalculationsButton
calculate={this.calculate}
cardRarity={this.state.cardRarity} />
</div>
);
}
}
export default App;
CardDatabase.js
import common from './Common';
import rare from './Rare';
import epic from './Epic';
import legendary from './Legendary';
const CardDatabase = (props) => {
const card = props.cardRarity;
const level = props.cardLevel;
let filteredArray = [];
let pushedArray = [];
let reducedArray = [];
const array = (rarityOfArray) => {
filteredArray = rarityOfArray.filter(item => item.key <= level)
for(let x = 0; x < filteredArray.length; x++) {
pushedArray.push(filteredArray[x].cardsRequiredToUpgrade)
console.log(pushedArray);
}
reducedArray = pushedArray.reduce((a, b) => a + b, 0);
console.log("Reduced - " + reducedArray);
return reducedArray
}
if(card === "9586") {return array(common)}
if(card === "2586") {return array(rare)}
if(card === "386") {return array(epic)}
if(card === "36") {return array(legendary)}
if(card === "") {return null}
}
export default CardDatabase;
Folks on Reddit and Discord were giving me the same feedback, I shouldn't be using a component if said component isn't returning anything UI-related. Therefore, CardDatabase.js
shouldn't be a component but a simple function instead.
I changed its name to cardDatabase.js
so that React no longer considers it a component and instead of it receiving props, the function now has standard parameters.
Updated cardDatabase.js
import common from './Common';
import rare from './Rare';
import epic from './Epic';
import legendary from './Legendary';
const cardDatabase = (cardRarity, cardLevel) => {
let filteredArray = [];
let pushedArray = [];
let reducedArray = [];
const array = (rarityOfArray) => {
filteredArray = rarityOfArray.filter(item => item.key <= cardLevel)
for(let x = 0; x < filteredArray.length; x++) {
pushedArray.push(filteredArray[x].cardsRequiredToUpgrade)
console.log(pushedArray);
}
reducedArray = pushedArray.reduce((a, b) => a + b, 0);
console.log("Reduced - " + reducedArray);
return reducedArray
}
if(cardRarity === "9586") {return array(common)}
if(cardRarity === "2586") {return array(rare)}
if(cardRarity === "386") {return array(epic)}
if(cardRarity === "36") {return array(legendary)}
if(cardRarity === "") {return null}
}
export default cardDatabase;
In App.js
I removed the <CardDatabase />
component and inside of my calculate
method, simply assigned the value of variable w
to my cardDatabase
function with this.state.cardRarity
and this.state.cardLevel
as the arguments.
Updated App.js
import React, {Component} from 'react';
// CSS
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
// Components
import CardRarityDropdown from './components/CardRarityDropdown';
import CardLevelDropdown from './components/CardLevelDropdown';
import CardAmountInput from './components/CardAmountInput';
import CardCalculationsButton from './components/CardCalculationsButton';
//Containers
import cardDatabase from './containers/cardDatabase/cardDatabase.js';
class App extends Component {
constructor() {
super();
this.state = {
cardRarity: "",
cardLevel: "",
amountOfCards: "",
}
this.setCardValues = this.setCardValues.bind(this);
}
setCardValues = (event) => {
const {name, value} = event.target
this.setState({
[name]: value
})
}
calculate = () => {
let rarity = this.state.cardRarity;
let level = this.state.cardLevel;
console.log("v: " + rarity)
let w = cardDatabase(rarity, level);
console.log("w: " + w)
let x = rarity - w;
console.log("x: " + x)
let y = this.state.amountOfCards;
console.log("y: " + y)
let z = x - y;
console.log("z: " + z)
return z
}
render () {
return (
<div>
<h1 id="superCellText">Clash Royale Card Calculator</h1>
<CardRarityDropdown
setCardValues={this.setCardValues}
cardRarity={this.state.cardRarity} />
<CardLevelDropdown
setCardValues={this.setCardValues}
cardRarity={this.state.cardRarity}
cardLevel={this.state.cardLevel} />
<CardAmountInput
setCardValues={this.setCardValues}
cardRarity={this.state.cardRarity}
amountOfCards={this.state.amountOfCards} />
<CardCalculationsButton
calculate={this.calculate}
cardRarity={this.state.cardRarity} />
</div>
);
}
}
export default App;
Now w
is returning a numerical value instead of an object and my app is finally functioning properly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.