react triggers onclick when component is mounted - reactjs

I am passing a component to a nested component a onClick method that modifies the state of the parent component.
Somehow the method is being called when a component (not sure if it's parent or child) is being mounted. And now, I'm getting the following error message:
Uncaught Error: Invariant Violation: setState(...): Cannot update
during an existing state transition (such as within render). Render
methods should be a pure function of props and state.invariant
The code for passing the child looks like the following
var playlists = this.props.data.map(function(playlist) {
return (
<PlaylistItem key={playlist.id}
data={playlist}
showPlaylistCode={this.getPlaylistCodeData}
/>
);
}.bind(this));

In your Playlist Item component, line 20, try changing it to:
<div className="playlistCode i mfi-qr-code" onClick={this.props.showPlaylistCode.bind(this, this.props.data.id)}></div>
When you need to send an argument to a function that's used onClick in React, you need to use bind. As with any use of bind(), the first argument should be the context of this, and the second should be what you want to send to the click handler function.

Related

how to know the component rendering condition in react js

I have one component which is rendering as child as well or user can navigate to that component directly from menu of UI. I am facing one issue now is, if that component as child then its working fine but when I click upon menu to navigate directly then my getDerivedStateFromProps() function is throwing an error as
TypeError: Cannot read property 'length' of undefined
Below is my code. It will work fine if I send a data from parent component to this component and render it from parent component.
static getDerivedStateFromProps(props, state) {
if (props.data.length)// this line is throwing an error when I directly come to this component from menu {
const data = props.data;
return { custData : data };
}
return null;
}
How can I check the condition that not to execute above logic if I am coming to this component directly.
You can double-check like this :
if (props.data && props.data.length)
Check to see if the data exists
if (props?.data)

trying to call function in child component fails

I have two React components, Parent and Child, each is separate module in its own file. I'm using Redux, so both are "export default compose"...
In the Parent's constructor:
this.myChild = React.createRef();
In the Parent's render:
<Child ref={this.myChild} />
Child has method defined:
getAlert() {
//do something
}
I'm trying to call in one of Parent's method:
this.myChild.current.getAlert();
But I get:
this.myChild.current.getAlert() is not a function.
I verified that this.myChild.current is not null.
What am I missing?
Refs are used to access the DOM, not the React component (which is a JS class). As per the official docs on refs:
In the typical React dataflow, props are the only way that parent components interact with their children. To modify a child, you re-render it with new props.
Avoid using refs for anything that can be done declaratively. For example, instead of exposing open() and close() methods on a Dialog component, pass an isOpen prop to it.

passing data from child to parent in react and undefind is not a function

I need to pass an array from child component to my parent component .
What i did in parent component is :
handlerfordata=(data)=>{
console.log('Inside handlerfordata data is');
console.log(data);
}
Inide return in render .Note Child is name of my child component
return(
<View>
<Child handlerfordata={this.handlerfordata()}/>
</View>
);
Now inside my child component i have done something like this
handleSave = () => {
//finalvalue is an array that is computed and i can see it in my console and handlesave is triggeed at onclick in child component inside return
console.log('finalValue is ',finalValue);
this.props.handlerfordata(finalValue);
}
Another thing is that child component gets rendered on the screen but i just want to access data from child component and not rendering it .
Pass the reference for handlerfordata and not this.handlerfordata().
It shuld be
<Child handlerfordata={this.handlerfordata}/>
^^^^^^^^^^^^^^^^^^^^^^
By adding this code
<Child handlerfordata={this.handlerfordata()}/>
You are not passing the reference, rather you are calling this function.
Change it to
<Child handlerfordata={this.handlerfordata}/>
which will just pass a reference.
Then you can call that from child component using props.
You have to bind your handler :
<Child handlerfordata={this.handlerfordata.bind(this)} />
Inorder to call the method you need to pass the reference in the child element as
<Child handlerfordata={this.handlerfordata}/>
You cannot access the data from child without rendering the child component.I prefer you to use redux so that all the states are there in a single store.
ReactJS is known for one way data flow(Top down) meaning whatever data that is flowing or passing, should be in one direction, from parent to child.
In the case where you need to pass data the other way round, perhaps try to apply redux state management instead.
In the code that you are trying as stated, it's only passing a method down from parent to child.

TypeError when using focus()

I have a react component having a input box. I used componentDidUpdate to set the focus to the input box. But my tests are failing with a typeError. Following is my code . Help me to pass the tests. Than you!!
This is my react component
`
public inputBox: any;
componentDidUpdate = () => {
this.inputBox.focus();
}
<div>
<input
ref = {element => this.inputBox = element}
/>
</div>
`
When the component is updated the tests are failed. giving me this error
TypeError: Cannot read property 'focus' of undefined
can any body can tell me whats wrong here?
Based on the official docs:
Note that when the referenced component is unmounted and whenever the
ref changes, the old ref will be called with null as an argument. This
prevents memory leaks in the case that the instance is stored, as in
the second example. Also note that when writing refs with inline
function expressions as in the examples here, React sees a different
function object each time so on every update, ref will be called with
null immediately before it's called with the component instance.
I believe that the ref callback gets passed null when the input is unmounted (that probably happens when your test ends and a different test starts). I think you just need to test for null when you want to focus the element, like in the docs:
<TextInput ref={function(input) {
if (input != null) {
input.focus();
}
}} />

ReactJS Why can't I modify children passed into a component

I figured I could do this, but I am getting this error:
TypeError: child.constructor.ConvenienceConstructor is not a function
I have a component in a page, ala:
// this content is in an html page. My component reads in this child, but I can't seem to modify any part of it.. Just diplay it.
<MyComponent prop1="somevalue">
<div className="myclass1"> some child content that is dynamic </div>
</MyComponent>
Now, in my component since that inner child(ren) is dynamic, I need to change that class depending on some condition. But I can't. I get that error I noted above.
I tried this:
var childContent = React.Children.map(this.props.children,
function(child) {
return React.cloneWithProps(child,
{ className: 'myNEWClass' } );
});
I tried cloneElement too, that didn't work either.
Doesn't work. I tried accessing the child directly, ala:
child._store.props.className // but can't seem to change it, seems immutable.
So, how can I change that class up?
thanks,
Props are supposed to be immutable, so instead of passing className as a prop, you make the parent pass in a prop named defaultClass. In your map method, you can add an extra prop, say, overrideClass. Finally, in the render() method of the actual child component, you need some logic to set the className to either overrideClass, or defaultClass. In this way, you don't have to mutate props.

Resources