Answer the question
In order to leave comments, you need to log in
Animating numbers in React, what am I doing wrong?
Good day everyone.
I want to make an animation of numbers, for this I chose the library
https://github.com/glennreyes/react-countup
I connected it, in the render I output:
As a result, I get a black screen, and in the console the error is:<CountUp end= { 100 } />
Uncaught (in promise) TypeError: React__default.createRef is not a function at new CountUp (index.js:318)
/* @flow */
import React from "react";
import isEqual from "lodash/isEqual";
import { stringify as b } from "rebem-classname";
import { withLocalize } from "react-localize-redux";
import { Translate } from 'react-localize-redux';
import CountUp from 'react-countup';
import Player from "./Player";
import Clan from "./Clan";
import "./Players.scss";
import type { PlayerType, GeneralType } from "../types";
function secondsToClock(_seconds, delim = ":") {
const minutes = Math.floor(_seconds / 60);
const seconds = _seconds - (minutes * 60);
return `00${minutes}`.slice(-2) + delim + `00${seconds}`.slice(-2);
}
const block = "players";
class Players extends React.Component {
state = {
width: 0,
playerWidth: 0,
offset: 0,
isShowArrows: false,
isShowView: true,
};
componentDidMount() {
setTimeout(() => this.updatePlayers(), 0);
}
componentWillReceiveProps(nextProps) {
if (!isEqual(nextProps.players, this.props.players)) {
this.setState({ isShowView: false }, () =>
setTimeout(() => this.setState({ isShowView: true }), 10),
);
}
}
componentDidUpdate(prevProps) {
if (!isEqual(prevProps.players, this.props.players)) {
this.updatePlayers();
}
}
props: {
state: "WAITING" | "COUNTDOWN" | "CULMINATION" | "ENDED",
players: PlayerType[],
general: GeneralType[],
gameId: number,
fund: number,
timer: number,
};
updatePlayers = () => {
const { players, general } = this.props;
const playersLength = players.length;
if (playersLength <= 0 || !this.view) return;
const idx = general.length - 1;
let player = this.view.children[0].children[idx];
let playerMargin = parseFloat(window.getComputedStyle(player).marginLeft);
if (player.className === "clan") {
player = player.children[0].children[general[idx].players.length - 1];
if (playerMargin <= 0) {
playerMargin = parseFloat(window.getComputedStyle(player).marginLeft);
}
}
const playerWidth = player.offsetWidth + playerMargin;
const width = (playersLength * playerWidth) - playerMargin;
this.setState({
width,
playerWidth,
isShowArrows: this.view.clientWidth < width,
});
};
handleArrow = d => () => {
const { width, playerWidth, offset } = this.state;
const maxOffset = width - this.view.clientWidth;
let newOffset = offset + (d * playerWidth);
if (newOffset < 0) {
newOffset = 0;
} else if (newOffset > maxOffset) {
newOffset = maxOffset;
}
this.setState({ offset: newOffset });
};
render() {
const { state, players, general, timer, fund, gameId } = this.props;
const { width, offset, isShowArrows, isShowView } = this.state;
return (
<div
className={b({
block,
mods: {
show: (state === "WAITING" || state === "COUNTDOWN") && players.length > 0,
},
})}
>
<div className={b({ block, elem: "container" })}>
<button
className={b({ block, elem: "arrow-btn" })}
hidden={!isShowArrows}
onClick={this.handleArrow(-1)}
>
<i className="fa fa-chevron-left" />
</button>
<div
className={b({ block, elem: "view", mods: { show: isShowView } })}
ref={view => {
this.view = view;
}}
>
<div
className={b({ block, elem: "list" })}
>
{general.map((obj: GeneralType) => {
if (obj.clanId) {
if (obj.players.length === 1) {
const player = obj.players[0];
return <Player key={`p${player.userId}`} player={player} />;
}
return <Clan key={`c${obj.clanId}`} clan={obj} />;
}
return <Player key={`p${obj.userId}`} player={obj} />;
})}
</div>
{/* Игра #{gameId} */}
<div className={b({ block, elem: "time-bank"})}>
<div className={b({ block, elem: "time"})}>
{secondsToClock(timer)}
</div>
<div className={b({ block, elem: "bank"})}>
<i className="fa fa-database" />
< CountUp end= { 100 } />
{fund}
</div>
</div>
<div
className={b({ block, elem: "lists" })}
>
{general.map((obj: GeneralType) => {
if (obj.clanId) {
if (obj.players.length === 1) {
const player = obj.players[0];
return <Player key={`p${player.userId}`} player={player} />;
}
return <Clan key={`c${obj.clanId}`} clan={obj} />;
}
return <Player key={`p${obj.userId}`} player={obj} />;
})}
</div>
</div>
<button
className={b({ block, elem: "arrow-btn" })}
hidden={!isShowArrows}
onClick={this.handleArrow(1)}
>
<i className="fa fa-chevron-right" />
</button>
</div>
</div>
);
}
}
export default withLocalize(Players);
Answer the question
In order to leave comments, you need to log in
<div className={b({ block, elem: "time-bank"})}>
<div className={b({ block, elem: "time"})}>
{secondsToClock(timer)}
</div>
<div className={b({ block, elem: "bank"})}>
<i className="fa fa-database" />
< CountUp end= { 100 }>
{({ countRef }) => (
<span ref={countRef}></span>
)}
</CountUp>
{fund}
</div>
</div>
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question