Here is my exemple :
https://codesandbox.io/s/test-uz-713xy
As you can see in this rather nice example,
I try to assign 2 differents methods to 2 differents buttons ("skyfall" and "vileMurder").
But these methods are calling from outside of my class, they are therefore not correctly recognized and I got the following error message : skyFall is not defined
or vileMurder is not defined
is anyone know how to fix that for me please ?
Those function are indeed not defined in the scope you are calling them.
This can be fixed in two steps:
1. Pass the functions as props from the Profils component
<IsHeStillAlive
skyFall={this.skyFall}
vileMurder={this.vileMurder}
panel={panel}
And change the mapping function to take a lambda instead of function because functions bring their own this variable bound to the function context.
this.state.data.map((panel) => {
2. Use the props from IsHeStillAlive
<Button onClick={() => props.vileMurder()}>
...
<Button onClick={() => props.skyFall()}>
The changes above will be enough to have the functions recognised and executed but there are other errors down the line, also related to the context of this. I recommend that you read the MDN doc about this.
You could also be interested to convert your components to react hooks. Although it is not mandatory, this is now the recommended way to define components and it prevents most of the context binding issues to happen.
Related
Say I have a React component that looks like this:
const MyReactComponent = (props) => {
const my_function = () => {// do some stuff...}
return (
<div>
<p>
Hello {props.name}, would you like to eat a {my_function()}?
</p>
</div>
)
}
Would the code defining my_function be re-evaluated every time My_React_Component is used? (By "used", I mean "appears in the JSX.")
Yes. Sort of. Maybe no.
When executing a javascript function each line in the function will get executed/evaluated. So the function definition will be evaluated again each time your function is called. Since you are using a function component then yes, the function will get redefined not only each time your component is used but also each time it is re-rendered.
However, does it mean that javascript recompiles the function each time it is defined? Maybe. In theory javascript does not need to recompile the function. It only needs to create a new closure. In theory you do not need to recompile a function to create a new closure - you just need a copy of the function's stack frame. Due to heavy competition from Netscape4 onwards most javascript interpreters have been optimised to such an extent that almost no modern javascript interpreter will recompile the inner function again. So the slowest part of function definition happens only once.
Still, in theory this still gives class-based components a small advantage over function components: the function definition does not need to be evaluated again on each render. In practice the performance difference is very small.
If you really insist on avoiding reevaluating the function definition you can always declare it outside of the component. This will surely evaluate the function only once. However you cannot use closures to share variables with the function but this is not much of an issue as you can always pass the variables into the function. Declaring functions outside of components also encourage you to write pure functions because of the inability to share closures:
const my_function = (propsArgs) => {// do some stuff...}
const MyReactComponent = (props) => {
return (
<div>
<p>
Hello {props.name}, would you like to eat a {my_function(props)}?
</p>
</div>
)
}
Do you mean Used or re-rendered?
In case of when you meant Used:
Yes every component acts as it's own instance hence the methods are executed every time when the function is either called or component is rendered initially (if used on rendering), But if you use the component at multiple times on the DOM, it writes the script only once. The markup is duplicated for that part of DOM, however the script isn't.
when only initialize, maybe you can use
React.useEffect(() => {
const my_function = () => {console.log('my_function')}
my_function();
}, [])
I have the following component:
<MaxFrContainer data-test="wellness-report-card">
<PrimaryBlueButton
onClick={() => {
// open popup
}}
>
generate
</PrimaryBlueButton>
</MaxFrContainer>
Jest complains that the onClick call isn't tested, but how do I test it? Whatever he callback would be, it is defined within the component and not passed down as a prop. Also, this similar thing repeats in my code. Sometimes it opens a popup, sometimes it makes an API call.
How do I get these tested
Can you be more specified what do you do in //open popup?
If I would create such component there are should be separate module with business logic, and in onClick handler I should just call some method from this module.
<MaxFrContainer data-test="wellness-report-card">
<PrimaryBlueButton
onClick={() => MaxFrContainerController.clickHandler()}
>
generate
</PrimaryBlueButton>
</MaxFrContainer>
And to test onClick you should only check that clickHandler of mock MaxFrContainerController was called.
I have a Class Component in a React App. It works. Then I need a global variable and reached to the React's Contexts. I create Context and can consume its value.
But I need to update its value, I read a lot and it seems I have to use React Hooks to update Context value. But my components are Class Components and there I cant use hooks.
My question is, If I want to use Contexts, I cant use Class Components? Right now Im learning React and encountered to Hooks many times. If hooks very important thing, This means we have to use Function Components all the times?
What I have to do? I just need to update my global variable and use its value.
If I want to use Contexts, I cant use Class Components?
No, you can use context either in Class Components.
See Context section in docs, all examples are with classes.
We have to use Function Components all the time?
No, you can use any approach you see fit.
But, there is no actual reason to use Class Components any more (except implementing Error Boundary). React officially recommends using hooks and composition, therefore the preferable approach is Function Components.
What I have to do? I just need to update my global variable and use its value.
A global variable as the name stands, its global to the application's scope (and not bound to component's scope like state). You can update it from everywhere.
const globalObject = { name: `myVar` };
// Can be updated from any scope as you keep the reference.
const FunctionComponent = () => { globalObject.name=`a`; return <></>; }
// Outer scope
globalObject.name=`b`;
Please visit this link, https://www.taniarascia.com/using-context-api-in-react/ and How to update React Context from inside a child component?.
it is explained in this link, you can do this way :
class LanguageSwitcher extends Component {
render() {
return (
<LanguageContext.Consumer>
{({ language, setLanguage }) => (
<button onClick={() => setLanguage("jp")}>
Switch Language (Current: {language})
</button>
)}
</LanguageContext.Consumer>
);
}
}
I am getting the below error while binding the values to the function.
TypeError: Cannot read property 'bind' of undefined
Please see the code below:
<button className={classes.ButtonStyle} onClick={props.onClickHandler.bind(null,props.id)}>{props.children}</button>
But the arrow function notation is working fine though:
onClick={(e)=>{props.onClickHandler(props.id,e)}}
May I please know where I have done wrong? Also I am not using class based components but only functional based components(hooks).
The onClickHandler function is as below:
const onClickHandler = (id, e) =>{
e.preventDefault();
console.log('buttonSetNullHandler', id);
}
It's difficult to know for sure without looking at your program as a whole, but here's what's possibly happening:
With the arrow function style, props.onClickHandler is evaluated at the time the button is clicked.
With the bind style, the bind will be executed when the component first mounts.
My guess is that when the component first mounts, props.onClickHandler is not set, but it is being set in a subsequent render that happens before you click the button.
It should be easy to check by putting a console.log(props) in the render function and seeing how many times it happens and what the props are each time.
As an aside, I personally would go with the arrow style over the bind style - onClick={e => props.onClickHandler(props.id,e)} is likely to be much less surprising to the developer coming after you. :)
I am learning React via an online course and have stumbled across a situation where a property is attached to another property like so:
this.props.property01(this.props.property02)
Seeing as the tutor only briefly addresses this line of code I cannot but remain baffled as to what this "concatenation" syntax actually stands for, i.e. what it causes behind the scenes. Coming from Vanilla JS it looks like property02 is being used as an argument for property01 but that seems too simple an answer. That being said, I understand the remaining code quite well.
To provide some context I have created this codepen in which the problem I refer to above is given by this.props.onDelete(this.props.whichItem);.
Seeing as I could not find any related questions, I would be grateful for some insightful elaboration on this one.
The properties of a React component can be functions. When I see:
this.props.property01(this.props.property02)
I think that:
this.props.property01 is a function.
this.props.property02 is passed to the function as an argument.
This means that the component would be used as:
<SomeComponent property01={(a) => { /* so something with "a" ... */ } property02={"someValue"} />
If property02 is only used to be passed to property01 and nothing else I would prefer something like:
<SomeComponent property01={(a) => { /* do something with "someValue" ... */ } />
Which means that there is no need for a property called poperty02.
Coming from Vanilla JS it looks like property02 is being used as an argument for property01
That's it, you are correct.
this.props.property01(this.props.property02)
property01 is a method, property02, the argument.
A more elaborated explanation for anyone else looking at this:
Assume this line is in a component called MyComponent and property01 is a prop in MyComponent.
The parent component's render() method, would contain something like this:
<MyComponent property01={this.someMethod.bind(this)} />
Where someMethod belongs to that parent component but it becomes available as property01 in MyComponent (the child component).
If you can understand the basic react code this question will help you because in that code I passed props and state from parent component to the child component. You can play with it try to do whatever you want.
How to pass state from parent compont to child component in route (react-route-dom) reactjs