I'm trying to set up an if statement in React-native, but it wont work properly - react-native

I have a function if statement set up to check if one user-input number is bigger than another user-input number, and then subtract the bigger number from the smaller one to create the answer to the problem. But whenever I run the code, sometimes it will work fine, but usually, it will only ever select the first number as the bigger one.
import React, { Component } from 'react';
import { AppRegistry, Text, View, StyleSheet, TextInput, TouchableHighlight } from 'react-native';
import Constants from 'expo-constants';
export default class App extends Component {
state = {
num1: 0,
num2: 0,
num3: 0,
message: ' ',
};
subtractSmallerNumber = () => {
if (this.state.num1 > this.state.num2) {
this.setState({
num3: (this.state.num1 - this.state.num2),
message: 'num1 is bigger',
})
} else {
this.setState({
num3: (this.state.num2 - this.state.num1),
message: 'num2 is bigger',
})
}
}
I tried rewriting the code but I'm not sure if it's a syntax error. I'm not really sure what to do because I just started working with react native and I don't know a lot yet, but I wasn't sure what to look up online.

It would be beneficial to see the full code as its unclear if the error could be happening within the function you have provided. Also what are the default state values (if any)?
I would hazard a guess that your numbers are probably being evaluated as strings, so it could do with it being cast as a Number. The code you provided can be cleaned up without the use of an if/else statement too with the use of a ternary operator, so your function only every relies on 1 useState, like so:
subtractSmallerNumber = () => {
const { num1, num2 } = this.state;
const isBigger = Number(num1) > Number(num2);
this.setState({
num3: isBigger ? Number(num1) - Number(num2) : Number(num2) - Number(num1),
message: `${isBigger ? 'num1' : 'num2'} is bigger`,
});
};

Related

Add CoreUI icon to DevExtreme dxDataGrid column header in Vue.js

Currently I am working on a new UI for a legacy API. Unfortunately, this one delivers HTML source code for a column header. This code usually creates a FontAwesome icon. This library will not be used in the new project.
I found a very similar icon in the Icon Library of CoreUI. Now it is only a matter of rendering the icon at this point. However, no approach has been successful so far. How can I replace the icon in the headerCellTemplate method?
Or maybe there is a completely different, much better approach to do this. I don't know if I am on the right track with this method approach. You can probably use static templates, but I don't know how to do that.
import { CIcon } from '#coreui/vue';
import { cilCheckCircle } from '#coreui/icons';
headerCellTemplate: (element, info) => {
element.innerHTML = curr.ColumnTitle;
if (element.firstChild.nodeName === 'I') {
// WORKS
//element.firstChild.innerHTML = 'Done';
// ANOTHER EXPERIMENT
//const componentClass = Vue.extend(cilCheckCircle);
//const instance = new componentClass();
//instance.$mount();
//element.removeChild(element.firstChild);
//element.appendChild(instance.$el);
// ALSO NOT WORKING
return CIcon.render.call(this, cilCheckCircle);
}
}
I finally found a solution after revisiting this interesting article.
import Vue from 'vue';
import { CIcon } from '#coreui/vue';
import { cilCheckCircle } from '#coreui/icons';
headerCellTemplate: (element, info) => {
element.innerHTML = curr.ColumnTitle;
if (element.firstChild.nodeName === 'I') {
const cIconClass = Vue.extend(CIcon);
const instance = new cIconClass({
propsData: { content: cilCheckCircle }
});
instance.$mount(element.firstChild);
}
}
I don't know, though, if this is the ideal solution. So feel free to tell me, if you have a better, less complex solution.

Change Ant Design Pro Table pagination language

I have already set the ProTable's language to en-US. Everything is translated to English already but the pagination footer still is in Chinese. How can I change the pagination language to English?
import ProTable, { ProColumns, IntlProvider, enUSIntl } from '#ant-design/pro-table';
const ProTableList: React.FC<{}> = () => {
return (
<IntlProvider value={enUSIntl}>
<ProTable<TableListItem>
headerTitle="Example List"
actionRef={actionRef}
rowKey="key"
...
/>
...
</IntlProvider>
)
}
If you use Ant Design with Pro Components than you need to use Internationalization from non pro version of Ant Design.
Wrap your App or in this case only ProTable component with ConfigProvider like in code below and you will get english translate.
import React from 'react';
import { ConfigProvider } from 'antd';
import enUS from 'antd/lib/locale/en_US';
import ProTable from '#ant-design/pro-table'
const YourComponent = () => {
return (
<ConfigProvider locale={enUS}>
<ProTable />
</ConfigProvider>
);
}
export default YourComponent;
I figured it out but forgot to update the answer here. The ProTable component has a showTotal method under pagination. You can use the provided total and range variables to modify the displayed pagination text.
import ProTable, { ProColumns, IntlProvider, enUSIntl } from '#ant-design/pro-table';
const ProTableList: React.FC<{}> = () => {
return (
<IntlProvider value={enUSIntl}>
<ProTable<TableListItem>
headerTitle="Example List"
actionRef={actionRef}
rowKey="key"
...
pagination={{
showTotal: (total, range) => (
<div>{`showing ${range[0]}-${range[1]} of ${total} total items`}</div>
),
}}
/>
...
</IntlProvider>
)
}
Will result in this:
Encountering the same issue, I think it's a bug. You can disable it by setting
showTotal to false
pagination={{ showTotal: false }}

ReactJS - app functions in different files

I'm trying to make React-based web game. I have an App component which holds pretty much all non-UX state. To avoid code duplication I also hold most functions in it and pass it down as prop to child components.
But now I'm starting to get cluttered by different functions, all in the App body. Is there any simple way to satisfactory structure this in different files? Should I already look into state management libraries?
Currently stuff looks like:
class App extends Component {
constructor(props) {
super(props);
this.state = gameInitialize();
this.modifyState = this.modifyState.bind(this);
this.moveUnit = this.moveUnit.bind(this);
this.progressMission = this.progressMission.bind(this);
this.timeJump = this.timeJump.bind(this);
this.competenceAfterTimeJump = this.competenceAfterTimeJump.bind(this);
this.save = this.save.bind(this);
this.load = this.load.bind(this);
}
componentDidMount() {
this.timerID = setInterval(this.modifyState, this.state.interval);
window.addEventListener('beforeunload', this.save);
this.load();
}
componentWillUnmount() {
clearInterval(this.timerID);
}
save() {
localStorage.setItem("gameSave", toJson(this.state));
}
load() {
let state = 0;
try {
state = fromJson(localStorage.getItem("gameSave"));
} catch (error) {
console.log(error);
return 0;
}
state.units.map(unit => {
delete unit.__parent;
delete unit.attributes.__parent
return 0;
});
state.missions.map(mission => delete mission.__parent);
this.setState(state);
}
modifyState() {
this.setState(this.state.units.map(this.progressMission));
this.setState(this.state);
}
progressMission(unit) {
const mission = unit.currentMission;
let increment = unit.attributes[mission.type].total() - mission.complexity;
if (increment < 0) increment = 0;
mission.progress += increment * this.state.interval / 1000 * unit.competence / 10;
if (mission.progress >= mission.difficulty) {
mission.progress = 0;
this.state.experience.get(mission.reward);
mission.completions += 1;
}
}
moveUnit(unit, mission) {
unit.currentMission = mission;
this.setState(this.state);
}
timeJump() {
const game = this.state;
while (game.units.length > 2) {
game.units.pop();
};
game.units.map(function (unit) {
Object.keys(unit.attributes).map((key) => { unit.attributes[key] = newAttribute() });
unit.currentMission = game.missions[0];
});
game.missions.map((mission) => {mission.progress = 0});
game.units[0].competence = this.competenceAfterTimeJump();
game.experience.current = 0;
this.setState(game);
}
competenceAfterTimeJump() {
return (10 + Math.sqrt(this.state.experience.total) / 10);
}
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="title">Time-traveling Hero: eventually I'll save the world, or maybe not if I don't feel it</h1>
</header>
<SaveLoad game={this} />
<Prestige game={this} />
<MissionWrapper>
<MissionList missions={this.state.missions} game={this} />
</MissionWrapper>
<UnitWrapper>
<ExpWrapper>
<div>
Available Experience: {this.state.experience.current.toFixed(1)}
</div>
<div>
Total Experience: {this.state.experience.total.toFixed(1)}
</div>
</ExpWrapper>
<UnitList units={this.state.units} game={this} />
</UnitWrapper>
</div>
);
}
}
function gameInitialize() {
let game = { units: [], missions: [], currentUnit: undefined };
game.interval = 10;
game.missions = generateMissions(50);
game.experience = {
current: 0, total: 0,
get: function (amount) { this.current += amount; this.total += amount },
spend: function (amount) {
if (this.current >= amount) {
this.current -= amount;
return true;
}
else return false;
}
};
game.units.push({ name: "Hero", attributes: newAttributes(), competence: 10, currentMission: game.missions[0] });
game.units.push({ name: "Childhood Friend", attributes: newAttributes(), competence: 15, currentMission: game.missions[0] });
game.currentUnit = game.units[0];
game.missionsWithUnits = function () {
this.missions.map()
}
return game;
}
How should I proceed?
Yes, it's super easy to organize JS code! Use modules. Here's how to do it.
Export functions from a file
adders.js:
export function addTwo (number) {
return number + 2
}
Then use it:
This could be in a component file:
import { addTwo } from './path/to/adders.js'
console.log(addTwo(5)) // logs 7
You can organize this super well for a lot of things. If you have a group of related functions, use a module like this. here's the file structure:
mathStuff/
adders.js
index.js
You have all of your related files in the same folder and your functions exported from the individual files like above. Then set up index like this:
index.js:
import * as adders from './adders.js'
// Set up your object however you want.
const MathStuff = {
...adders
}
export default MathStuff
Then in any component you can do this:
import MathStuff from './path/to/mathStuff'
MathStuff.addTwo(7) // 9
For even more organization, you could set your index up to have functions like this:
index.js:
import * as adders from './adders.js'
import * as dividers from './dividers.js' // another math file with division functions or something
// Set up your object however you want.
const MathStuff = {
adders,
dividers
}
export default MathStuff
And use it like this:
import MathStuff from './path/to/mathStuff' // points to directory, NOT individual file
MathStuff.adders.addTwo(7) // 9
I would definitely suggest organizing code like this. One thing this improves is testability - it's very easy to test pure functions with no side effects.
I like to put my database code in one module and import it wherever to access all my database functions.
I like to put all of my business logic in different modules by category - for instance GameLogic or something like that.
This will also help you write more functional code. Currently, you have a lot of state modification within individual functions - you won't be able to do that in modules without binding individual functions to the this context of your react component. Instead, I would suggest passing all necessary parameters to the function and having it return a value. This moves business logic away, making it easier to manage state.
For instance, your progressMission function accesses this.state.interval. You can pass interval to the function itself.
One thing I'm noticing is that your code has a lot of dependency on each other - functions often have to access lots of things outside of itself, rather than being self-contained. It would probably help you a lot to try to refactor into a modular system, where functions are much more pure - only accessing what is passed to them, and returning values which get used. Using actual modules like above definitely helps do that - my code got better the more I did it. It helps you reason about your code better. Additionally, once/if you start implementing tests, you'll find that all of the tangled-ness of the code makes it hard to test - there are a lot of side effects.
Finally, redux and external state management probably won't help a ton in your case, but they might. Redux can help you achieve state that's easier to reason about, but it won't help you organize code better per se. I hope that helps!

jest snapshot testing: how to ignore part of the snapshot file in jest test results

Problem: ignore some part of the .snap file test results
the question here: there are some components in my test that have a random values and i don't really care about testing them. is there any way to ignore part of my X.snap file? so when i run tests in the future it won't give me test fail results.
Now you can also use property matcher for these cases.
By example to be able to use snapshot with these object :
const obj = {
id: dynamic(),
foo: 'bar',
other: 'value',
val: 1,
};
You can use :
expect(obj).toMatchSnapshot({
id: expect.any(String),
});
Jest will just check that id is a String and will process the other fields in the snapshot as usual.
Actually, you need to mock the moving parts.
As stated in jest docs:
Your tests should be deterministic. That is, running the same tests multiple times on a component that has not changed should produce the same results every time. You're responsible for making sure your generated snapshots do not include platform specific or other non-deterministic data.
If it's something related to time, you could use
Date.now = jest.fn(() => 1482363367071);
I know it's quite old question but I know one more solution. You can modify property you want to ignore, so it will be always constant instead of random / dynamic. This is best for cases when you are using third party code and thus may not be able to control the non deterministic property generation
Example:
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Card from './Card';
import toJSON from 'enzyme-to-json';
Enzyme.configure({ adapter: new Adapter() });
describe('<Card />', () => {
it('renders <Card /> component', () => {
const card = shallow(
<Card
baseChance={1}
name={`test name`}
description={`long description`}
imageURL={'https://d2ph5fj80uercy.cloudfront.net/03/cat1425.jpg'}
id={0}
canBeIgnored={false}
isPassive={false}
/>
);
const snapshot = toJSON(card);
// for some reason snapshot.node.props.style.backgroundColor = "#cfc5f6"
// does not work, seems the prop is being set later
Object.defineProperty(snapshot.node.props.style, 'backgroundColor', { value: "#cfc5f6", writable: false });
// second expect statement is enaugh but this is the prop we care about:
expect(snapshot.node.props.style.backgroundColor).toBe("#cfc5f6");
expect(snapshot).toMatchSnapshot();
});
});
You can ignore some parts in the snapshot tests replacing the properties in the HTML. Using jest with testing-library, it would look something like this:
it('should match snapshot', async () => {
expect(removeUnstableHtmlProperties(await screen.findByTestId('main-container'))).toMatchSnapshot();
});
function removeUnstableHtmlProperties(htmlElement: HTMLElement) {
const domHTML = prettyDOM(htmlElement, Infinity);
if (!domHTML) return undefined;
return domHTML.replace(/id(.*)"(.*)"/g, '');
}
I used this to override moment's fromNow to make my snapshots deterministic:
import moment, {Moment} from "moment";
moment.fn.fromNow = jest.fn(function (this: Moment) {
const withoutSuffix = false;
return this.from(moment("2023-01-12T20:14:00"), withoutSuffix);
});

React Native Syntax

Excuse the noobie question, but when I am going through the react native docs there are syntax differences to regular javascript. I am trying to figure out where the docs are that describe the syntax.
For example this statement
var {
ActivityIndicatorIOS,
StyleSheet,
View,
} = React
And the use of the => operator in
setToggleTimeout: function() {
this.setTimeout(
() => {
this.setState({animating: !this.state.animating});
this.setToggleTimeout();
},
1200
);
},
Those are ECMAScript 6 features
Your first example is a destructuring assignment
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
And the second one is an arrow function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Accepted answer above is correct, but here are some examples:
First: an example of ES6 Destructuring:
var {
ActivityIndicatorIOS,
StyleSheet,
View,
} = React
is exactly analogous to:
var ActivityIndicatorIOS = React.ActivityIndicatorIOS;
var StyleSheet = React.StyleSheet;
var View = React.View;
This is a nice shorthand approach. Of course, destructuring is more powerful than that and the Mozilla docs give further examples.
2nd: An example of an ES6 arrow function (or fat arrow function)
setToggleTimeout: function() {
this.setTimeout(
() => {
this.setState({animating: !this.state.animating});
this.setToggleTimeout();
},
1200
);
},
Advantages are a less code to write, but a critical difference is that in arrow functions the 'this' is the same 'this' as the context it is written in. In other words, you don't have to use bind() anymore.
The bad old days:
setToggleTimeout: function() {
this.setTimeout(
function() {
this.setState({animating: !this.state.animating});
this.setToggleTimeout();
}.bind(this),
1200
);
},