I'm using React to display a Material Design Grid List of news articles. Im passing the JSON I receive to this GridList component (this.props.newsArticles), and mapping through each returned result so I can filter the data based on whether it has a hi-def image, then sending the data to MediaTile to get rendered. I'm having a problem with my ternary in GridList module's hasHiDefPictures function. I receive a syntax error.
const Components = {
MediaTile: React.createClass({
render: function() {
return (
<GridTile
title={this.props.tile.title}
>
<img src={this.props.tile.multimedia[0].url} />
</GridTile>
)
}
}),
GridList: React.createClass({
render: function() {
var newsArticles = this.props.newsArticles
var renderArticles = newsArticles.data.results.map(function(tile, key) {
return hasHiDefPictures(tile, key)
})
function hasHiDefPictures(tile, key) {
return {tile.multimedia > 3 ? <Components.MediaTile key={key} tile={tile}/> : ""}
};
return (
<div>
<GridList>
{renderArticles}
</GridList>
</div>
);
}
})
}
Now the only way to get around this syntax error is to wrap that returned value in div's like so:
function hasHiDefPictures(tile, key) {
return (
<div>
{tile.multimedia > 3 ? <Components.MediaTile key={key} tile={tile}/> : ""}
</div>
)
};
But I do not want to do that. Does anyone have advice on how to get around this problem? I'm still new to react, so there's a good chance that I'm just not handling the data in the proper place. Any help would be appreciated! Thanks!
You just need to remove the {} around your ternary. {} is useful in JSX (an expression starting with <) to evaluate some JS code, but your array mapping already occur in pure JS code (the beginning of the render function) so it has the regular JS meaning: a block or an object literal.
Related
I have a function component like that
function myMainComponent() {
const MyUIA() {
//some calulations about attrs
return (<div><ComponentA {...attrs}></div>)
}
const MyUIB() {
//some calulations about attrs
return (<div><ComponentA {...attrs}></div>)
}
// Way A
/*
return (
<div>
<MyUIA/>
<MyUIB/>
</div>);
*/
// Way B
return (
<div>
{MyUIA()}
{MyUIB()}
</div>);
}
The results of render by WayA and WayB is the same, but in first case there is a flickering
So why the WayB has better performance without flickering ?
What is the best way to render part of renders thas exist in the same function component ?
does WayA and WayB have a specific name for example "render by calling native method" and "render by calling JSX method" in react ?
Since as we know every code we write in react is converted into JSX first, then it get rendered so if we see for native method the JSX element is created twice while for JSX it's created only once. So this is the case one can see the flickering. I hope it helps.
function myMainComponent() {
const MyUIA = () => {
return /*#__PURE__*/React.createElement("div", null,/*#__PURE__*/React.createElement(ComponentA, null)); };
const MyUIB = () => {
return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(ComponentA, null));};
// Way A
return /*#__PURE__*/React.createElement("div", null,
/*#__PURE__*/React.createElement(MyUIA, null),
/*#__PURE__*/React.createElement(MyUIB, null));
// Way B
return /*#__PURE__*/React.createElement("div", null, MyUIA(), MyUIB());
}
In my react page i'm building a html table. table rows are generated from a child component as follows 'ViewGRNTable'. Upto this page is working great
also i want to get a value from every row in child component and add it to the 'this.state.GRNtotal'. for that I wrote a callback function 'callbackRowSum' which returns 'rowsum' and add value it to this.state.GRNtotal
ViewGRNCartTableRow(){
return this.state.cartProducts.map(function(object,i){
return <ViewGRNTable obj={object} key={i} callbackSum = {this.callbackRowSum} />;
});
}
callbackRowSum = (rowsum) => {
this.setState({GRNtotal: this.state.GRNtotal+rowsum})
}
but it gives an error TypeError: Unable to get property 'callbackRowSum' of undefined or null reference
please help
That's a binding issue, change your function for an arrow function
ViewGRNCartTableRow(){
return this.state.cartProducts.map((object,i) => (
<ViewGRNTable
obj={object}
key={i}
callbackSum={this.callbackRowSum}
/>
));
}
It's because you're not binding the this keyword to the function being passed to map, you can solve that easily with the arrow function or you can manually bind your function like this
ViewGRNCartTableRow(){
return this.state.cartProducts.map(function(object,i){
return (
<ViewGRNTable
obj={object}
key={i}
callbackSum={this.callbackRowSum}
/>
);
}.bind(this));
}
I have an API that I'm attempting to filter out every title with a rating of 'Rx'.
The returned json data is stored within a variable called dataItems.
Example: If I want to return the rating for the first object, I'd do dataItems[0].rated
My attempt to filter out anything rated "Rx" is the following.
class AnimeCard extends Component {
render() {
const { dataItems } = this.props
console.log(dataItems)
return (
<AnimeCardWrapper>
{dataItems.filter(item => item !== item.rated['Rx']).map((item, index) => {
return (
<AnimeCardItem>
<PosterImg src={item.image_url} alt="poster" />
<CardTitle key={index}>{item.title}</CardTitle>
<p>{item.score}</p>
<p>{item.rated}</p>
</AnimeCardItem>
)
})}
</AnimeCardWrapper>
)
}
}
Doing so gives me the following error: "TypeError: item.rated is null"
I've attempted to pull out the string "Rx" into a variable and then do rated[rxVariable], but I still receive the same error.
I also attempted to use Object.values(), but I still had no luck. I'm sure there's something I'm overlooking.
Just to be clear, I'd like to display every item except those with rated: "Rx"
I believe you should change the line dataItems.filter(item => item !== item.rated['Rx'] to dataItems.filter(item => item.rated !== 'Rx'
I'm wondering how to dynamically request a component based on a variable value. What I'm trying to accomplish here is the following:
import Template1 from './Template1.jsx';
import Template2 from './Template2.jsx';
var ComponentTemplate = (some_condition === true) ? "Template1" : "Template2"
render() {
<ComponentTemplate prop1="prop1 val" />
}
Is this even possible? If so, how?
It is not clear to me why you need to use a string representation of a class rather than just switch the component or use a conditional render:
var Component = some_condition === true ? Template1 : Template2;
// ...
return ( <Component /> );
But assuming this is an oversimplification, the easiest thing to do would be to use a mapping object that translates a string into a component. With ES2015 enhanced object literals, it becomes fairly straightforward:
var Components = {
Template1,
Template2,
};
var Component = condition ? Components['Template1'] : Components['Template2'];
// ...
return ( <Component /> );
If you are just looking to render different component based on the condition you could actually have 2 other render function and inside render() you could check the condition and call corresponding render
render () {
!this.state.isAuthorized? renderLogin(): renderTweets();
}
renderLogin () {
<LoginView/>
}
renderTweet () {
<ListTweets/>
}
Hope this is what you were looking for!
All the dynamic rendering should inside Render function. Because the JSX compile will depend on the Variable name not the Object reference.
If you write <Component />,
it will transfer to React.createElement('Component').
Cannot refer to the dynamic component you want to choose.
depend on the condition when Render is running. Use different React tag you want.
render() {
condition ? <Template1 /> : <Template2 />
}
The React Tutorial has a render apparently returning an array of rendered nodes:
// tutorial10.js
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment) {
return (
<Comment author={comment.author}>
{comment.text}
</Comment>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
What are acceptable return types for a render() method for a component? An array seems to work? What about an array of arrays? If I have data stored in an array of arrays of codes, how do I appropriately render the grid?
You must always return a react component, but the contents of that component (as long as they are valid jsx syntax) can be an array, an array of arrays containing react components. E.g.
var MyComponent = React.createClass({
render: function () {
var single = <p>Single</p>;
var array = [
<p>One</p>,
[<p>Two</p>],
[<p>Three</p>]
];
return (
<div>
{single}
{array}
</div>
);
}
});
React.render(<MyComponent />, document.body);
jsbin
Typically you would take the data, iterate over it (however many levels deep) and generate your components. Array.Map and other "functional" helpers are particularly helpful in situations like this.
If you check the docs you'll see that you can only return a component or null/false from render.
"The render() method is required. When called, it should examine this.props and this.state and return a
single child component. This child component can be either a virtual
representation of a native DOM component (such as or
React.DOM.div()) or another composite component that you've defined
yourself.
You can also return null or false to indicate that you don't want
anything rendered. Behind the scenes, React renders a tag
to work with our current diffing algorithm. When returning null or
false, this.getDOMNode() will return null."
http://facebook.github.io/react/docs/component-specs.html