Why can't I use "this" in the JSX rendered html element?
My question is about conditional rendering in JSX and usage this
.
In my React app, consider the following code:
render() {
return (
<li onMouseEnter={this.mouseEnter}>
//things
</li>
)
}
I would like to conditionally render the attribute onMouseEnter
so that it is not applied every time the component is invoked and the tag is displayed <li>
.
For example:
render() {
return (
<li {this.renderMouseEvents()} >
...
</li>
)
}
But the visual studio complains and says that "[js]" ... "expected"
Obviously, calling { this.renderMouseEvents() }
outside the HTML element accepts use this
.
Why is it this
invalid inside html element in JSX?
What's the correct / cleaner way to accomplish this conditional rendering in JSX?
Any help is appreciated, thanks!
source to share
What you wrote is not valid JSX syntax. Try this instead:
mouseEnterBehaviorEnabled()
is a function that returns true
or false
. This is where you put your logic when you want to mouseEnter
run.
Take a look at Assessing Short Circuits on MDN.
render() {
return (
<li onMouseEnter={this.mouseEnterBehaviorEnabled() && this.mouseEnter} >
...
</li>
);
}
Surely you could just do
render() {
return (
<li onMouseEnter={this.mouseEnter} >
...
</li>
);
}
and run your logic inside mouseEnter
before the rest of the original behavior. If those conditions don't work, just return false and the rest will fail.
source to share
You can do this using the spread operator (ES6) and logical AND short-circuit evaluation:
...{ onClick: condition && this.handleClick }
Example:
const arr = ["1", "2", "3"];
class App extends React.Component {
constructor(props) {
super(props);
}
handleClick = e => {
console.log(e.target.innerHTML);
};
render() {
return (
<div>
{arr.map(o => {
const myProps = {
...{ onClick: o != "1" && this.handleClick }
};
return (
<li {...myProps}>
{o}
</li>
);
})}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
source to share
You can use this
in JSX, I don't think this is a problem.
If the problem is this
, it could be inside your method renderMouseEvents
, are you bind
up to this
?
But I think it doesn't work because of what your method returns renderMouseEvents
. While it is possible to inject properties, to check it out, it might help:
source to share
If I understand what you are asking, I believe the problem you are having is related to how JSX is converted to JavaScript.
<el arg1="1" arg2="2">3</el>
converts to something similar to the following:
React.createElement('el', { arg1: '1', arg2: '2' }, '3');
What you wrote is likely to be translated this way if yours renderMouseEvents()
returns { onMouseEnter: this.mouseEnter }
:
React.createElement('li', { { onMouseEnter: this.mouseEnter } }, '...');
This is invalid JavaScript. The compiler tells you what it expects ...
(JavaScript distribution syntax) which will probably solve this problem.
As noppa mentioned, there may be better ways to achieve what you want. Can you elaborate on the problem you are facing?
source to share