Add Input Field onClick stateless component React Electron - reactjs

I'm new to electron, and working on trying to get React/Typescript with Hooks and ApplicationContext to all come together. I didn't create the framework and I need to learn how to make this work. Just setting the context to avoid answers like, use Redux instead. :)
I have a function stateless component that is a form. It needs to be stateless so I have access to values that are held in ApplicationContext. I'm trying to render extra input fields on button click, and so far when I click the button Electron calls the method, and then re-renders. I have searched high and low, and have been banging my head on this for a few hours. I apologize in advance if there is already an answer out there.
So far the code that displays the button looks as such:
<div className="form-group">
<button onClick={() => addUrls()}>
Add a URL
</button>
</div>
And the method is just printing to the console at the moment. It looks as such:
const addUrls = () => {
console.log('clicked')
}
the print statement is getting to the console, and then Electron re-renders. The rest of the component's methods are called, and are behaving in a predictable way. I'm really confused as to why this particular action is causing renders. If anyone can point me in the direction of an answer, or point out where I am doing something dumb in my code, I would be very much grateful.

Try replacing onClick={() => addUrls()} with onClick={addUrls}. The former method will create a new reference on every render, possibly causing rerenders.

Turns out I was doing something dumb. Because my button is inside a form, and I didn't specify the button type, it was doing the default behavior of "submit" which causes a render with the onClick.
The solution was to add type="button" to the button and now it's solved.
<div className="form-group">
<button onClick={addUrls} type="button">
Add a Reference URL
</button>
</div>
I hope this can save someone some time if they come across this problem in the future.

Related

How do I use custom Javascript in Next js

Coming from React, i am really confused. In pages/index.js, suppose I have a button with onClick listener, and clicking on that button will log "you clicked" in the console. How do i implement this? I want that page to be statically generated and also give that button some functionality.
The reason I am having a lot of trouble is because in React tutorials or even in my projects, if i needed some functionality i'd do this:
function handleClick() {
document.body.style.background = "black"
console.log("you clicked") //nothing is logged in console
}
export default function App() {
return(
<button onClick{() => handleClick}>Click Me</button>
)
}
I was gonna use this Next.js to see how state works. But I encountered a different problem. Unless I use inline function in onClick, it doesnt work. If I use a seperate handleClick function, the DOM doens't even show that I had an onclick event. I learned that's because Nextjs is rendered server side, so it doesnt have access to DOM and console etc. Then how do i do this?
I just transitioned from React, and in every tutorial, those guys would use handleClick func or whatever to handle events and stuff. But I couldnt find a solution to do this in Next, how does everyone handle this then? Because pages have interactive buttons right? Are those pages not statically generated then?
You forgot call function handleClick:
<button onClick{() => handleClick()}></button>
the same way you do it in react with your onClick function
Static generation pre-rendering does not change the interactivity of any page, check the following from Next.js documentation :
Each generated HTML is associated with minimal JavaScript code
necessary for that page. When a page is loaded by the browser, its
JavaScript code runs and makes the page fully interactive. (This
process is called hydration.)
https://nextjs.org/docs/basic-features/pages

Why this strange thing happening to my DOM element?

So I basically started learning react-redux and I am in the middle of creating some simple store app. I would introduce my problem in a few bullet points.
I have got a basic store with some states and the Navbar where I have the Cart button.
After the click of the cart button, I want to open the cart list and rotate the Cart icon for 90deg.
I want to put everything in the one function and attach it to onClick()
my code looks like that: https://codepen.io/szygendaborys/pen/wZYZor?editors=0010
The main problem is that all works if I cancel the statement after else. That one:
else {
style = 'none';
cartArrow.style.transform = 'rotate(0deg)'
}
If I put back that statement, I receive an error: TypeError: Cannot read property 'style' of null connected to
cartArrow.style.transform = 'rotate(0deg)'
Can anyone help me and explain why the if statement works and else does not?
Your cartArrow element likely hasn't rendered at the point of your DOM query (getElementById), which is an anti-pattern in React to begin with. Make use of refs instead.
<i
ref={(ref) => this.cartArrow = ref}
id='cartArrow'
className="fas fa-angle-right"
></i>
this.cartArrow.style.transform = 'rotate(0deg)'

I am trying to understand why componentDidUpdate is not firing for specific component

I am having some issues with a particular component not properly updating. This component is effectively modeled after each of the other components, the only difference that I can determine is that it receives props that are array elements; although I have switched the variable being passed so that it renders store elements that are working elsewhere, though I am still getting the same update issue.
The weird thing about this is that the component update does fire, but only when one of the other elements that is properly updating is triggered, so it logs the console object on this instance for two different checks within the componentDidUpdate function.
The overall design is a basic React/Redux app, with a component that is designed to hold/render the audio events. I have a MainLayout component that renders the AudioEngine component, followed by multiple "Panel" components that are only specified for the UI. It is this component that is passed the redux store. It appears that the redusx store is handling state properly, and is passing the data back as expected; however, it is only this element of the UI that is failing to properly trigger an update.
Within the AudioEngine component:
if(this.props.lfoRate != prevProps.lfoRate){
console.log(this.state.lfoRate)
this.setState({
lfoRate: this.props.lfoRate
}, () => {
this.lfo['osc'].frequency.value = this.state.lfoRate
});
}
Here is the return from the MainLayout component, which receives the stor/props (sorry this is still a bit of a work in progress):
return(
<div >
<Header />
<div style={mainLayoutStyle} className={"main-layout"}>
{
this.props.keyOn ? (<AudioEngine lfoRate={this.props.LFObj[2]} gain={this.props.masterGain} freq={this.props.masterFreq} oscArray={this.props.oscArray}
lfoType={this.props.LFObj[1]} lfoFreq={this.props.LFObj[3]} count={count}/>) : (count % 2 == 0 ? (<AudioEngine count={0} gain={0} freq={this.props.masterFreq} oscArray={this.props.oscArray}
lfoType={this.props.LFObj[1]} lfoRate={this.props.LFObj[2]} lfoFreq={this.props.LFObj[3]}/>) : (''))
}
<MainPanel keyToggle={this.props.keyToggle} changeMasterGain={this.props.changeMasterGain}
masterGain={this.props.masterGain} keyOn={this.props.keyOn} baseFrequency={this.props.masterFreq}
changeBaseFrequency={this.props.changeBaseFrequency} />
<div style={{display: 'flex', flexFlow:'column'}} >
<Oscillator addOsc={this.props.addOsc} subOsc={this.props.subOsc} oscArray={this.props.oscArray} />
<LfoPanel lfoRate={this.props.LFObj[2]} lfoFreq={this.props.LFObj[3]} onChange={this.props.changeLFO}
lfoType={this.props.LFObj[1]}/>
</div>
</div>
</div>
)
The LfoPanel component is designed much of the same way as the others...
Any pointers would be quite helpful, perhaps it is passing array elements as properties? If that is the case, that seems like a strange gotcha. Thank-you in advance...
Ok, so after some further research, I realized that it was in fact a mutability issue from Redux. Even though it was technically updating the state, it was not properly immutable. I ended up using the primary solution from this question.
Thanks to those who looked / took time to respond. Hopefully this reference will save another React-Redux a headache later on :)

React dynamically rendered component not updating

I'm trying to render a list of components using map function in render. When I change state, render function is called as expected but my component is not updated.
I've made a sample codesandbox here
https://codesandbox.io/s/nk24mr55om
What am I doing wrong?
I've added some console logs and it look like secret content should be displayed but it is not
Once your item is pushed into the items array, it will not be updated, ever. A solution to this would be to convert the items you push into arrow functions that will get a show parameter :
items.push(show =>
<div>
{show && <div>I'm secret</div>}
My content
<br />
<input
type="button"
onClick={showSecret}
value="Show secret content"
/>
</div>
);
And then call it in the mapping of your render :
return <div key={index}>{item(show)}</div>;
However, with this solution, clicking on one button will cause every item to show their secret element, if this isn't the behavior you expect and want every item to act on its own, I suggest creating a hook for each item. And ahev them store their own show variable in their state.
I have no experience yet with react hooks, but i tried to understand whats going on.
The variable items you refer to is neither a prop nor in the state of your component, i would make the component stateful and initialize items in the state.
Maybe there is a better way with react hooks that someone else can give

Can't get ref of underlying button?

Using react-bootstrap: I'd like to get the DOM node of the actual button (why? because I'm using clipboardJS which requires a DOM node event handler), but this ref doesn't work:
<Button ref="myButton">Click me!</Button>
The ref returned there is to the Button component, not the actual button node. Of course I could do:
const buttonNode = ReactDOM.findDOMNode(this.refs.myButton)
But findDOMNode is going away and I'd really like to avoid that hack if possible. It would seem like react-bootstrap could use a Component-level prop to help in these situations:
<Button innerRef="myButton">Click Me!</Button> {/* wishful thinking... */}
What am I misunderstanding? Much thanks for any help.

Resources