Answer the question
In order to leave comments, you need to log in
How to share responsibility in React and how to solve the problem with notifying the state of a Model change?
I'm learning React, JavaScript, doing a test project - Gym Journal.
Exercise
, it: handleChange
, handleSubmit
) Set
( handleWeightChange
, handleRepsChange
, toggleMaxReps
) Set
( addSet
, getSet
, updateSet
), and itself ( changeWeight
, changeReps
). import React from "react";
import generateUniqueId from "../utils/generateUniqueId";
import Set from "./Set";
class Exercise extends React.Component {
constructor(props) {
super(props);
this.state = {
id: generateUniqueId(),
label: null,
confirmed: false,
sets: [],
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleWeightChange = this.handleWeightChange.bind(this);
this.handleRepsChange = this.handleRepsChange.bind(this);
this.toggleMaxReps = this.toggleMaxReps.bind(this);
}
handleChange(event) {
this.setState({label: event.target.value});
}
handleSubmit(event) {
this.setState({
confirmed: true,
sets: [{id: generateUniqueId(), weight: null, reps: null, enableMaxReps: false}]
})
event.preventDefault();
}
handleWeightChange(event, id) {
this.updateSet({
id,
updatedSet: {weight: event.target.value},
listener: (sets) => this.addSetWhenPrevSetFilled(sets)
});
}
handleRepsChange(event, id) {
this.updateSet({
id,
updatedSet: {reps: event.target.value},
listener: (sets) => this.addSetWhenPrevSetFilled(sets)
});
}
toggleMaxReps(id) {
let set = this.getSet(id);
if (set) {
set.enableMaxReps = !set.enableMaxReps;
this.updateSet({id, updatedSet: set});
}
}
addSetWhenPrevSetFilled(sets) {
let lastSet = sets[sets.length - 1];
let isNeedEmptySet = true;
for (let key in lastSet) {
if (lastSet[key] === null) {
isNeedEmptySet = false;
}
}
if (isNeedEmptySet) {
this.addSet({weight: null, reps: null});
}
}
addSet({weight, reps, enableMaxReps}) {
enableMaxReps = enableMaxReps || false;
this.setState({
...this.state,
sets: [
...this.state.sets,
{id: generateUniqueId(), weight, reps, enableMaxReps}
]
});
}
getSet(id) {
for (let set of this.state.sets) {
if (set.id === id) {
return set;
}
}
return null;
}
updateSet({id, updatedSet, listener}) {
updatedSet = updatedSet || {};
this.setState({
...this.state,
sets: this.state.sets.map((set) => {
if (set.id === id) {
return {
...set,
...updatedSet
};
}
return set;
})
});
if (typeof listener === "function") {
setTimeout(() => {
listener(this.state.sets);
}, 1000)
}
}
render() {
return (
this.state.confirmed ?
<ExerciseView
id={this.state.id}
title={this.state.label}
sets={this.state.sets}
changeReps={this.handleRepsChange}
changeWeight={this.handleWeightChange}
toggleMaxReps={this.toggleMaxReps}
/> :
<ExerciseFormView onSubmit={(e) => this.handleSubmit(e)} onChange={(e) => this.handleChange(e)}/>
);
}
}
function ExerciseView({id, title, sets, changeWeight, toggleMaxReps, changeReps}) {
return (
<div className="col-12" key={id}>
<h5>{title}</h5>
<table className="table table-bordered">
<tbody>
{sets.map((set, index) =>
<Set
set={set}
changeWeight={(e) => changeWeight(e, set.id)}
changeReps={(e) => changeReps(e, set.id)}
toggleMaxReps={() => toggleMaxReps(set.id)}
number={index + 1}
/>)}
</tbody>
</table>
</div>
);
}
function ExerciseFormView({onSubmit, onChange}) {
return (
<div className="col-12">
<form onSubmit={onSubmit}>
<div className="input-group mt-4 mb-4">
<select className="custom-select" id="select-exercise" onChange={onChange}
aria-label="Select workout type">
<option defaultValue>Выбрать...</option>
<option value="Жим лежа">Жим лежа</option>
<option value="Отжимания">Отжимания</option>
<option value="Тяга гантели">Тяга гантели</option>
</select>
<div className="input-group-append">
<button className="btn btn-outline-secondary" type="submit">Начать</button>
</div>
</div>
</form>
</div>
);
}
export default Exercise;
SetCollection
- manages an array of approaches ( SetCollection.add()
, SetCollection.remove()
) Set
- manages its data ( Set.create()
, Set.changeMaxWeght()
, etc.) forceUpdate()
to the class constructor SetCollection
, Set
and call it when the data changes. Set
, management of its form (functions) to carry out there. Answer the question
In order to leave comments, you need to log in
To manage the state, you need to use one of the state management libraries.
One of the most popular right now is Redux. There is also Mobx, for example. There are other new fashionable ones - read the comparison on the request "alternatives to Redux" or here's the article: https://habr.com/ru/company/ruvds/blog/566102/
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question