Access Objects within a JSON Array in a React Component - arrays

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.

Related

Issues using react-loading-overlay

I have a simple react app, and im trying to add a simple loading overlay.
I saw the most common usage is react-loading-overlay.
My main app.js structure looks like that, I have a simple menu and a deck.gl map
<div className="container">
<AppMenu/>
<div className="deckgl_map">
<DeckMap/>
</div>
</div>
If I get it correctly, to use the loading overlay, I need to do something like that (using true for testing):
<LoadingOverlay
active={isActive}
spinner
text='Loading your content...'
>
<div className="container">
<AppMenu/>
<div className="deckgl_map">
<DeckMap/>
</div>
</div>
</LoadingOverlay>
But once I do that, my entire app page, instead of filling the whole screen, just takes the top 20% of the screen (and the rest is empty white).
Why wrapping my component with the LoadOverlay component causes the whole page to look weird?
Do I need to "play" with the CSS for the LoadOverlay component?

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

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>

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

How to get value when React wraps content in spans?

I have a React component that renders some html like below, with one callback method (this.deleteItem) triggered upon click of an x. In the callback method, I try to get the content associated with each of the two refs like this
var date = this.refs.date.getDomNode.value;
var content = this.refs.content.getDomNode.value;
but the result is undefined in both cases. When I simply do this.refs.content.getDomNode (instead of looking for the value) it shows me a div with some span tags inside, and inside of one of those is the content I was seeking. Similarily with the date ref, it is a <small></small> element with spans inside.
Question: how to get the value/content from a div or element when react wraps content in spans?
<div ref="wrapperdiv">
<span className="delete" onClick={this.deleteItem}>x</span>
<small ref="date"> {date} </small>
<div ref="content"> {content } </div>
</div>
This is a known limitation of react, in that it wraps any floating text nodes in a span because it has to handle the data-reactid of the component. See this question too.
Perhaps if you tried to remove the white space around the content?
<div ref="wrapperdiv">
<span className="delete" onClick={this.deleteItem}>x</span>
<small ref="date">{date}</small>
<div ref="content">{content}</div>
</div>
Also try:
this.refs.content.getDomNode().children[0].textContent
to get the value of the span. (Not sure if there is a react specific function for this). This will have to be done as well as removal of the white space within:
<small ref="date">{date}</small>
<div ref="content">{content}</div>
This is important because react generates span tags to handle the data-reactid. Take a look at: Rid of repeated spans in React.js?.

How to make Reactjs not rerender certain components

So I'm trying to build a full page in Reactjs but some components are persisted throughout pages. The structure is something like this:
<div>
{showHeader ? header : ''}
{showNav ? nav : ''}
<div className="main">
<section className="left">
{this.props.children}
</section>
<section className="right>
<section className="persist-this"/>
{moreStuff}
</section>
</div>
</div>
During rerendering is the structure change is significant enough (changing from a page with header & nav to no header/no nav the persist-this section will be re-rendered as well.
Right now I'm actually doing React.renderComponent for each individual pieces & keep the structure static (so like renderComponent for header, nav, left section & moreStuff separately) & I wonder if there's a better way to doing this?
EDIT: I think I do know why this got re-rendered. I guess my question now becomes more like how to organize my structure better. So I got BasePage.jsx which has the structure above & in other pages (like HomePage.jsx or OtherPage.jsx) I do:
var HomePage = React.createClass({
render: function () {
<BasePage>
<p>Home</p>
</BasePage>
}
});
I think when I do React.renderComponent it see <HomePage> & <OtherPage> as 2 completely different Components although they are wrapped by the same <BasePage>, thus unmounting the Page. Should I separate the differences of those pages into mixins?, then always renderComponent(<BasePage>, el) to prevent unmounting?
If something persists between pages, the correct way to do it would be to separate your structure so that whatever persists only shares an ancestor which also persists.
In other words, you should structure it like this:
<div id="siteRoot">
<div className="dynamic">
{showHeader ? header : ''}
{showNav ? nav : ''}
<div className="main">
<section className="left">
{this.props.children}
</section>
</div>
</div>
<div className="persist-this">
<section className="right>
<section/>
{moreStuff}
</section>
</div>
</div>
Then your css should adapt to your new dom hierarchy and update your layout accordingly.
Now when you switch content in your dynamic section, React will automatically know that it doesn't need to re-render anything in the persist section - since nothing was changed there.

Resources