is it ok practice to call components from other components in react, rather than the render?
just feels wrong but components both using state not directly sharing data without telling this.state. so i think why not
is it ok practice to call components from other components in react, rather than the render?
Iām not sure what you mean by ācall componentā You nest them or use them. You should not be directly calling a render method.
just feels wrong but components both using state not directly sharing data without telling this.state. so i think why not
The state of each component is its own. They donāt share state, not directly. You can pass it as props, or share it with the context API or some state management tool (e.g., redux) but they donāt share state - there is no global state, just local to each component.
Iām still not sure Iāve understood. If that didnāt answer your question, could you give and example?
sorry, my style of learning seems to be to forget everything I just read about when I start the projects/practice stuff.
I was writing up some action creators inside the class component and just carried on writing every component into the class component, but maybe some need moving.
Iāll show my code so far, but the commented out pause() component was triggering the iterator() action, rather than render, hence my question.
(or [https://codepen.io/camalDan/pen/eYeOewb] )
function calcMinutes(secs){
let RemainerMins = secs % (60 * 60);
let answerMinutes = Math.floor(RemainerMins / 60);
return answerMinutes
}
function calcDisplaySeconds(secs){
let RemainerMins = secs % (60 * 60);
let RemainerSecs = RemainerMins % 60;
let displaySeconds = Math.ceil(RemainerSecs);
return displaySeconds
}
class CounterDowner extends React.Component {
constructor() {
super();
this.state = {
minutes: 25,
seconds: 1500,
displaySeconds: 0,
pausey: true,
};
this.timer = null;
this.iterator = this.iterator.bind(this);
this.countDown = this.countDown.bind(this);
this.plusMin = this.plusMin.bind(this);
this.minusMin = this.minusMin.bind(this);
// this.pause = this.pause.bind(this);
}
/*
componentDidMount() {
this.countDown(this.state.seconds);
this.setState({
minutes: this.state.minutes,
seconds: this.state.seconds,
displaySeconds: this.state.displaySeconds,
});
}
*/
iterator() {
this.setState((prevState)=>({
pausey: !prevState.pausey,
}));
if(this.state.pausey) this.timer = setInterval(this.countDown, 1000)
}
/*
pause() {
this.setState((prevState)=>({
pausey: !prevState.pausey,
}));
if(this.state.pausey) this.iterator();
}
*/
countDown() {
let nextSec = this.state.seconds - 1;
this.setState({
minutes: calcMinutes(nextSec),
seconds: nextSec,
displaySeconds: calcDisplaySeconds(nextSec),
});
if(this.state.pausey){clearInterval(this.timer);}
if (nextSec <= 0) {
clearInterval(this.timer);
}
}
plusMin() {
if(this.state.seconds < 3540){
this.setState((prevState)=>({
seconds: prevState.seconds+60,
minutes: calcMinutes(prevState.seconds+60),
}));
}
}
minusMin(){
if(this.state.seconds > 60){
this.setState((prevState)=>({
seconds: this.state.seconds-60,
minutes: calcMinutes(this.state.seconds-60)
}));
}
}
render() {
return(
<div>
<div className='setters'>
<button className='setButsLeft' onClick={this.plusMin}>+ </button><button className='setButsRight' onClick={this.minusMin}> -</button><br/>
</div>
<div className='centr'>
<h1 className='nums'>{this.state.minutes} : {this.state.displaySeconds}</h1>
</div>
<div className='controls'>
<button className="setControlLeft" onClick={this.iterator}><i className="fa fa-play"></i> / <i className="fa fa-pause"></i></button>
{/*} <button className='setControlMid' onClick={this.iterator}><i className="fa fa-pause"></i></button>*/}
<button className='setControlRight'><i className="fa fa-refresh"></i></button>
</div>
</div>
);
}
}
ReactDOM.render(<CounterDowner/>, document.getElementById('app'));
actually i found an example of what i meant in the given solution (not sure why we have access to a solution for projects but i donāt use it generally) :
Itās from the example 25+5 clock and timerControl() calls?/triggers? the beginCountDown() method I believe. So whatever that is referred to as is acceptable I guess?
timerControl() {
if (this.state.timerState === 'stopped') {
this.beginCountDown();
this.setState({ timerState: 'running' });
} else {
this.setState({ timerState: 'stopped' });
if (this.state.intervalID) {
this.state.intervalID.cancel();
}
}
}
beginCountDown() {
this.setState({
intervalID: accurateInterval(() => {
this.decrementTimer();
this.phaseControl();
}, 1000)
});
src: https://codepen.io/freeCodeCamp/pen/XpKrrW?editors=0010
I was writing up some action creators inside the class component and just carried on writing every component into the class component, but maybe some need moving.
Yeah, you definitely want to break things up. Codepen is a little weird for React in that you canāt break things into separate files. But each component should at least be its own class/function. But Iām not really seeing what youāre saying. For example, I donāt see any action creators.
Some thoughts on what Iām seeingā¦
You donāt need to bind your class methods if you use arrow functions.
This:
iterator() {
this.setState((prevState)=>({
pausey: !prevState.pausey,
}));
if(this.state.pausey) this.timer = setInterval(this.countDown, 1000)
}
is worrisome. There is no guarantee that that setState will be finished before that if
statement is evaluated. You can put that logic first or put it in a callback as a second parameter to the setState.
But Iām still not clear what your question is.
sorry, despite going over the course material more than once i find myself needing reminding the basics. Iām not trying to incorporate redux yet, so Iām not talking about āaction creatorsā but ācomponentsā.
your responses are probably more what I actually need to hear, rather than any answer to my dumb questions.
So basically Iām struggling to decide what should be within the main(?) class component, what should have itās own class component, and what should be a simple const component.
Is this in regards to a stateless functional component? meaning it doesnāt change state but only returns render from data/logic?
(Iāll set topic to solved, just to give my incoherent ramblings a low priority for your busy whizzos)
100% normal.
So basically Iām struggling to decide what should be within the main(?) class component, what should have itās own class component, and what should be a simple const component.
Yeah, that can be a struggle, knowing how to divide things up. It takes practice. In the beginning, I think that thinking visually, about the screen, is a great place to start.
As to class vs functional component, things are a little different in React now, but in this point of Reactā¦ The only things that should be class components are things that need state or lifecycle methods - everything else should be functional components.
You donāt need to bind your class methods if you use arrow functions.
Is this in regards to a stateless functional component? meaning it doesnāt change state but only returns render from data/logic?
No, FCs donāt have state (at least not in this version of React).
When this lesson was written, you had to bind this to your class methods in the constructor. Iām saying that if you make it an arrow function, then you donāt have to because the method will just inherit the classā this. Declare it like this:
iterator = () => {
Or donāt. Either works.
so you mean the UI?
so setting the ābreakā timer has itās own UI element, so itāll have itās own component.
but as the code is similar to the āsessionā timer code for running the ābreakā timer, and I am going to use the same UI element for the display clock, I may use that component (main) to run the ābreakā timer (as opposed to setting it), and therefore the ābreak timer settingā component would need to alter state?
and therefore should be a class component?
(sorry about number 2, I barely understand my own words, lol) But are my plans sensible here?
Sure, that is one way to think of it.
but as the code is similar to the ā session ā timer code for running the ā break ā timer, and I am going to use the same UI element for the display clock, I may use that component (main) to run the ābreakā timer (as opposed to setting it), and therefore the ā break timer setting ā component would need to alter state?
and therefore should be a class component?
If I understandā¦
Yes, if I have two clocks, I would create a generic clock component.
Should it be a class or FC. It needs access to its parentās state, not its own state. It probably doesnāt need its own state.
Remember that in vanilla React, there is no app state, only state for the individual components. So, the parent will pass its state into the child. And if the child to affect the parentās state, then the parent will also need to pass a callback function.
This can be a confusing pattern, so I once created this pen to help people understand. This pattern can get very messy with large apps - thatās where things like redux come in handy. But itās important to understand this pattern first.
To be clear, if I understand, no, they should not be classes because they donāt have their own state and donāt need lifecycle methods. But if it makes things easier for now, you can just make everything a class and change it later if needed.
that pen is just what i needed, thanks.
so
child 1: a stateless functional component (can use state frm parent to render something, but wont change state)
child 2: a stateful fuctional component where parents state is changed
child 3: altho useState is skipping a little ahead for me, this could be a class as it has, and renders, itās own state. but useState is a hook which means it can remain a stateful functional component but the declared variable is preserved between function calls, like state.
but also
ā¦but i could also put logic into the child component. If the logic is specific to that child, would that be preferable?
(thanks, mate. I shall endeavour to put that into practice without bothering the forum for the rest of the day, at least )
No, child two is a stateless FC. At the point in Reactās evolution, all FCs are stateless. They donāt have state until we get to hooks (which you havenāt learned yet). It has access to the parentās state but has no state of its own. It doesnāt even know or care that those values are some other componentās state. To it, they are just props.
child 3: altho useState is skipping a little ahead for me, this could be a class as it has, and renders, itās own state.
Yes, that is skipping ahead. That is a stateFUL FC, using a hook. In modern React, we donāt use classes much as FCs can have state. This didnāt exist when the lesson was made. So ignore this for now. Thatās fine, you need to understand classes.
ā¦but i could also put logic into the child component. If the logic is specific to that child, would that be preferable?
Iām not sure what you mean by ālogicā here. Do you mean keeping the state there? Then how would the parent have access? This is a pattern called ālifting up stateā, moving it to the common ancestor of all the components that need it. Again, this gets messy, which is why people like things like redux. But even with that, you still need to understand lifting up state.
Ah. stateless and stateful refer to a components own state, not parents, including when it changes it. ok.
No, I meant the JS functionality. Refering to the difference between passing in a (callback?) function as a prop, or performing itās own JS (which i called logic) before the return.
e.g. child 2 has increment = () => this.setState(oldState => ({ count: oldState.count + 1 }))
passed to it, but if it were specific to child 2 this function could be written into child 2.?
Sure, a child can have its own state, separate from an ancestorās state (that the child sees as props). There may be cases where you want this. Even with something like redux there are situations where you want a component to have and manage its own state.
Iāve finished (to my limited standards) the JS / JSX functionality of that project and I would appreciate any feedback just on the basic react structure. where the setState functions are located, how all others are outside the parent component, including at least one of each type class and FC. I couldnāt get the onClick
functionality to work in the reset component when i tried to make it an FC, but it worked as a class.
(I know there are other things, like correcting for drift in the timing and lots of CSS libraries begging for a run out. at the moment itās just the basic react structure/functionality Iām concerned about. )
OK, let me do a code review. Keep in mind that I can be kind of nitpickyā¦
All in all, things look pretty good. A few observationsā¦
function calcMinutes(secs){
let RemainerMins = secs % (60 * 60);
let answerMinutes = Math.floor(RemainerMins / 60);
return answerMinutes
}
Why are those āletā? In general, default to āconstā. The only time you need to use āletā is if you are going to need to reassign the variable. And why is āRemainerMinsā in PascalCase? Thatās usually reserved for components, classes, modules, and enums. This should be camelCase.
let styl = ''
First of all, thatās a terrible variable name. Secondly, if this is for a specific component, this should be in that component.
countDown=()=> {
let nextSec = this.state.seconds - 1;
this.setState({
minutes: calcMinutes(nextSec),
seconds: nextSec,
displaySeconds: calcDisplaySeconds(nextSec),
});
That should be a functional setState because it is based on the previous state, even if hidden in a variable. And the same thing a few lines later.
iterator = () => {
āiteratorā has a specific meaning in JS, I would avoid that name to avoid confusion.
Avoid cryptic names like āplusSnozā. Assume that the person reading your code does not know what you are thinking.
resetter = () => {
this.setState({
minutes: 25,
seconds: 1500,
displaySeconds: 0,
pausey: true,
snoozeTime: 300,
snoozeInput: 5,
snooze: false,
})
Rather than write out that object here and in the constructor, store it in a constant so you only have to write it once.
if(this.state.snooze == false){styl='centr'}else{styl='centrSnooze'}
This could be cleaner as:
styl = this.state.snooze ? 'centrSnooze' : 'centr'
but the variable should be declared here and probably as a const
.
resetterFunc
Naming variables is tough. I donāt like this name because you should not have to add āfuncā to it. A common practice is to name your functions as action verbs, so āresetā. Another is to name booleans starting with āisā (or āshouldā , ācouldā, āhasā, etc.) Then you read the variable and instantly know what it is. But yeah, sometimes naming variables is tough. But when done well, your code almost reads like a story.
class ClockSet extends React.Component { //THIS WONT WORK AS FUNC COMP. ONLY CLASS. DUE TO ONCLICK!?
No, that 100% should be an FC. Show me what youāve tried.
const audio = () => {
This is a component, it should be PascalCase.
But still, the basic ideas seems right. Itās mainly a bunch of nitpicky stuff.
That was a bunch of technical things. Later Iāll try to look at style.
Looking at this in more of a āthinking in Reactā veinā¦
<div className={styl}>
<h1 className='nums'>{this.state.minutes} : {this.state.displaySeconds}</h1>
</div>
Do you need that div
? I mean, could you apply that extra class to the h1
?
I would have a generic component that handles the break length and session length. The you pass in a label and callback functions. I mean, you could go even deeper and have generic buttons for the time adjust. That may seem silly on an application thus small, but it is part of thinking like a React developer.
Yeah, I was able to get ClockSet to work with a FC. Remember that there is no this.props, itās now ā¦
<div id="container"><div id="app"></div></div>
I would have put ācontainerā in my React code. I like to handle everything there.
I think the problem is Iāve displayed minutes and seconds in seperate elements and treated them seperately throughout, which I have to change a bit for passing tests, so Iāll implement as you suggest after coding that.
Ah! Good point. Except for the āfew lines laterā bitā¦
this.setState({
snooze: true,
seconds: this.state.snoozeTime,
minutes: this.state.snoozeInput,
});
I donāt see previous state in assignments.
canāt figure out how to declare as const
and assign hereā¦ (clockBackgroundColor
was styl
before)ā¦
render() {
// const clockBackgroundColor = this.state.snooze ? 'centrSnooze' : 'centr' // () => {}
this.clockBackgroundColor = this.state.snooze ? 'centrSnooze' : 'centr'
ā¦although it works like this.
baffled as to why changing to PascalCase causes <ReactAudioPlayer
to become unrecognised.
Itās ok, I had made simple sytax error to pass props. Fixed now.
Got a feeling StartPauseReset could be FC but wanted to use a class.
Thanks a lot for all your input. That was one of those where at first sight I had no idea what to do. I feel like Iām getting it now and some of the methods start to make sense.
new file is here:
https://codepen.io/camalDan/pen/gOXbxQW?editors=0010
ā¦although youāve helped me a lot already and Iāll move onto test passing/CSS stuff later today.
It has state in there. But it is a different section of state - maybe youāre right.
canāt figure out how to declare as
const
and assign hereā¦ (clockBackgroundColor
wasstyl
before)ā¦
That would depend on how youāre consuming it. There is no reason why that would have to be stored on the class.
baffled as to why changing to PascalCase causes
<ReactAudioPlayer
to become unrecognised.
There already is an HTML tag <audio>
so I would guess that before it wasnāt using your component. Now it is and it sees that that module isnāt defined. Because you imported it as camelCase. When I change the import to PascalCase, the error goes away.
Got a feeling StartPauseReset could be FC but wanted to use a class.
FCs are smaller and faster. And less typing. Always use an FC if you can.
That was one of those where at first sight I had no idea what to do. I feel like Iām getting it now and some of the methods start to make sense.
Trust me, we all remember. And React is such a weird thing when you start out.
Good luck. Let us know if you run into trouble on the rest of it.
whoops! yes, it would.
yes, i didnāt understand the audio part, did a bit of copy-paste coding . figuring it out now.
Thanks, again.