React JSX: How to avoid multiple onClick handlers for multiple elements - reactjs

New to React, coming from JS/jQuery land. Feel I have the basics down, but after quite a bit of searching, can't find the answer to the following issue. In jQuery, I can bind the same event handler to multiple child elements thusly:
$("#someId p").on("click", someFunction);
In React JSX, I've only figured out how to do the following, which seriously violates DRY, and reminds me of code I was writing years ago:
<div id="someId">
<p onClick={this.someFunction}>Foo</p>
<p onClick={this.someFunction}>Bar</p>
<p onClick={this.someFunction}>Baz</p>
</div>
There's gotta be a better way, yes?

You could put these p tags in list and use map function to render them.
let items=['foo','bar','baz'];
<div id="someId">
{items.map((a,index)=>{
return (
<p key={index} onClick={(event)=>this.someFunction(event,index)}>{a}</p>
);
})}
</div>

Related

Access Objects within a JSON Array in a React Component

I've got some JSON that I'm trying to access in React and grab specific pieces of data from, but I only want to pull from the first element in the array (the most recent financial data).
I've got the props on the component, but can't figure out how to get what I need. For instance if I want to access the debtRatios. I tried using map as I've done with the stock component, but it comes back as undefined. Ideally i'd like to have the data from ratio[0] as the props on the ratioInfo component.
<div className="stock-container">
<div className="stock">
{props.stock.map(stock => (
<UserStock key={stock.symbol} stock={stock}/>
))}
</div>
<div className="ratioInfo">
<UserStockRatios ratios={props.ratios}/>
</div>
</div>
Try this
<div className="ratioInfo">
{props.ratios.length > 0 && <UserStockRatios ratios={props.ratios[0]}/>}
</div>
Alternatively if you use babel in your project, this one might work as well:
<div className="ratioInfo">
<UserStockRatios ratios={props.ratios?.[0]}/>
</div>
More infos about Optional Chaining here.

How to add a HTML comment into a React component without extra nodes?

The idea is simple: I want to add a html comment into a rendered react without extra nodes.
This is my code:
render(){
return (
<div>
<ul>
<!-- i want this comment to be here -->
{items}
<!-- i want this other comment to be here -->
</ul>
</div>
)
}
The only way I found is using this:
<li dangerouslySetInnerHTML={{ __html: '<!-- comment -->' }} />
But this one adds me a new DOM node, which I don't need (nor want). So basically what I need is to generate markup like this:
<ul>
<!-- comment -->
<li></li>
</ul>
There is a way of doing this and I'm missing anything?
Edit: What problem I'm trying to solve?
The idea here is that I'm using React to only edit the content, which will be saved into DB as HTML. I know is not ideal, but we're talking WordPress here, so we have some wiggle room :)
Anyhow, the problem I'm trying to solve is that I want to create some kind of „hook” to the future me so I could alter the result dynamically (with a search & replace from PHP, so pseudoselectors aren't really useful here). HTML comments is the only way I could think that won't affect the output if is not used.
Thanks!
You can simply use javascript comments with curly braces.
Example:
render( ){
return (
<div>
{/* LIST STARTS HERE */}
<ul>
</ul>
{/* LIST ENDS HERE */}
</div>
)

Getting specific node from children props React

I'm quite new to React. Is there a way to get a specific node from an array of children props. So I have a component that accepts children. <CustomComponent> {children} </CustomComponent. Children property is an array of elements with a lot of child nodes.
<div> <h1> Title </h1> <p> Paragraph </p> <span> Text </span> <button> Text </button> </div>
Is there a way for CustomComponent to get only the <h1> tag using React.Children?
If possible, you can attach refs to child elements you want to fetch. So that you can do that :
this.props.children.refs['yourRefKey']
If I understand your question, this is doable by using the refs attribute and then accessing it later.
<input type="text" ref="myinput">
then
this.refs.yourref

Angular show-hide flickers

I'm switching the visibility of 2 elements when clicking them. A very simple use case:
<div ng-hide="filtersOpened"
ng-click="filtersOpened=true">
filters (opened)
</div>
<div ng-show="filtersOpened"
ng-click="filtersOpened=false">
filters (closed)
</div>
The change happens, but it flickers so that for a very short moment I see both elements together.
How can I make the change behave nicer, smoother, without the flickering? I've read about ng-cloack but doesn't seem like it's related since I'm not using a template.
Maybe try ng-if instead:
<div ng-if="filtersOpened" ng-click="filtersOpened=true">
filters (opened)
</div>
<div ng-if="!filtersOpened" ng-click="filtersOpened=false">
filters (closed)
</div>

React Component with subcomponents or render HTML in parent?

I have a question regarding React patterns. When rendering a component, is it appropriate for this component to render several sub-components, or is it ok to render some HTML in the parent component. Example:
If I have a box that has a heading and a body with list of elements, should I do:
var Box = React.createClass({
render: function() {
<div className="box">
<HeadingBox />
<BodyBox />
</div>
}
});
Or is it ok to do this:
var Box = React.createClass({
render: function() {
<div className="box">
<div className="heading">
<div> Heading1 </div>
<div> Heading2 </div>
</div>
<BodyBox />
</div>
}
});
Any rules to follow here?
It all depends on a context.
The general practice is that if you want to reuse the markup anywhere — you should go with the separate component, so you don't have to repeat yourself. Also if you find yourself writing a large portion of HTML (over 50 lines, for example), separating it into subcomponents will also help.
In other cases, just going with plain HTML will do.
You can find a good description on how best to organize your React code here. (section Separating UI details from interaction logic)
React is no different then other programming framework — it goes best with DRY (Don't repeat yourself).

Resources