How to define in which category display React component? - javascript

I have React component <Banner /> which is just an image (clickable and redirects to one of the categories), shown on the Home Page and belongs to 1 category eg. Ice-Cream (I have sidebar-menu with categories).
How can i check in which category to display this banner?
var Banner = React.createClass({
render: function() {
var toCategory = "/favourites";
var imageName = "Magnum Banner";
return (
<section className="banner" onClick={ this.props.onClick }>
<a href={toCategory}>
<img src={ window.assets['banner.png'] } width="1030" alt={imageName} ref="Banner" />
</a>
</section>
);
}
});
I was thinking about this way (this.state.ShowBanner) ? <Banner /> : null,
setting an Initial state to false in CategoryList component and then if window.location(?) equal to path in Banner component - setState to true
Pls help me with this issue. Thanks

Related

I have a component I want to appear once the timer is done

I have my component CountDownSquare I want to disappear once the timer is done fully counting down. I have Data in homePageData that holds the main text in a h3 element, this text should appear once the timer is fully done. Here's a ternary statement I attempt to assign but it isn't assigned to anything the way I thought it would be. Here is a snippet of what I thought of
const { homePageData } = props;
{homePageData[0].showCountdown ? <CountDownSquare/>: styles.homeBody}
return (
homePageData && (
<Layout>
<div className={styles.Home}>
<Image src={wordmark} alt="Hammer and Hope wordmark" />
<CountDownSquare >
</CountDownSquare>
{/* <div className={styles.homeBody}>
<h3 className={styles.mainText}>{homePageData[0].mainText}</h3> */}
<Nav />
</div>
</Layout>
)
);
} ```
I am assuming homePageData[0].showCountDown is a boolean which is true if the countdown is complete in the parent component.
You need to add conditions while rendering your component.
The following snippet will render the CountDownSquare component and the h3 tag with homePageData[0].mainText if homePageData[0].showCountdown is true.
const { homePageData } = props;
return (
homePageData ?? (
<Layout>
<div className={styles.Home}>
<Image src={wordmark} alt="Hammer and Hope wordmark" />
{homePageData[0].showCountdown ??
<CountDownSquare >
</CountDownSquare>
<div className={styles.homeBody}>
<h3 className={styles.mainText}>{homePageData[0].mainText}</h3>
</div>
}
</div>
</Layout>
)
);

Mapping an array with two different styles = odd array with one style and even array in other style

This is the standard mapping for blog posts in Gatsby and they show all the blog posts with a title, the date, and the post.
const { blogs } = data.strapi
const { id } = data.strapi.blogs
return (
<Layout>
<article>
<header>
<h1> {blogs.title} </h1>
<p> {blog.description} </p>
</header>
<hr />
</article>
</Layout>
)
};
export default BlogPost;
but how can I change the look that appears in the first blog post with the font to the right and color red; the second blog post title to the left and the color blue and so on?
I made an if conditional but I can't make it work
let even=blogs.filter((a,i)=>i%2===1); // 1 3 5
let odd = blogs.filter((a,i)=>i%2===0); // 0 2 4
<div>
{even.map((blog, i) => {
return <h1 className="text-danger">{blog.title}</h1>
})}
</div>
// Output : title[0], title[2], title[4]; all red
//Expected Output: title[0] (red), title[1] (blue), title[2] (red), title[3] (blue) title[4] (red), title[5] (blue);
Assuming you're using CSS to style your blog, you can just conditionally add the class name to style each element at the same time you loop through them to print it.
<div>
{blogs.map((blog, i) => {
return (
<h1 className={`text-danger ${i % 2 === 1 ? "isEven" : "isOdd"}`}>
{blog.title}
</h1>
);
})}
</div>

Error passing function onClick in react

I have two files. A list Component and a Single Item Component. In my app, the user can select multiples items. Then I create an state element in "list" "items" and my idea is that when the user make click on the item button, the list element notify to List Component and save the item in Items array from "list".
I have the next code
List.jsx:
registrarItems(data,item){
console.log(data,"aqui 1 con",item);
let items = this.state.itemsAgregados.slice();
if(!items.indexOf(data.id_producto)){
console.log("no se encuentra");
items.push(id);
this.setState({
'itemsAgregados':items
});
}else{
console.log("ya existe");
item.removerSeleccion();
}
console.log("registrando items",id);
}
render() {
return (
<div className="content-app">
<Navbar data={this.menu}/>
<div className="container lista-productos">
{
this.state.productos.map((producto, index) => {
return (
<Item data={producto}
registro = {this.registrarItems}
key={producto.id_producto}/>
);
})
}
</div>
</div>
);
}
And Item.jsx:
render() {
let props = this.props;
let img = JSON.parse(props.data.imagen);
let imgPath = Rutas.apiStatic + 'img/productos/' + props.data.id_producto + '/' + img.sm;
props.data.items = this;
return (
<div className="row item-listado">
<div className="col-xs-3">
<img src={imgPath} className="img-circle img-item"/>
</div>
<div className="col-xs-7">
<Link to={Rutas.producto + props.data.identificador}>
<h3 className="titulo">{props.data.titulo}</h3>
<span className="price">$ {props.data.precio}</span>
</Link>
</div>
<div className="col-xs-2 text-right">
<ul className="list-unstyled list-acciones">
<li>
<a href="#" onClick={()=>props.registro(props.data,this)} className={this.state.classAdd}>
<i className="fa fa-plus"></i>
</a>
</li>
</ul>
</div>
</div>
)
}
As you can see, I pass the "registrarItems" method as a param to Item and there, i add this as onClick event in the tag from item. But I need pass the "data" and the own "item" element to the onclick function. The first, for save the element clicked in the Items array, or remove it (if it already exists) because the button may have a toggle function. But in my "console.log" both params passed on the onClick method with the arrow function shows as "undefined".
I saw some examples and i don't get my error. can anybody helpme? thanks.
The final solve for this was simple. I resolved it with something similar as Free-soul said on his comment.
First, I passed the List Component as a param to item. Below my code in List's render method:
{
this.state.productos.map((producto, index) => {
this.items[producto.id_producto] = producto;
return (
<Item data={producto}
parent = {this}
key={producto.id_producto}/>
);
})
}
Then I get the parent param in componentDidMount method and later I call the validarItem function directly from the List method and I pass the params that i need.
Here my Item code:
onClickPlus(id,data) {
//{Rutas.listas + 'productos/' + props.data.id_producto //Url para pasar uno solo
this.setState({
classAdd:'selected'
})
if(!this.state.parent.validarItem(this.state.data)){
this.removerSeleccion()
}
if(this.state.seleccionMultiple){
}
}
removerSeleccion(){
this.setState({classAdd:'normal'})
}
componentDidMount(){
this.setState({
parent: this.props.parent,
data : this.props.data
})
}
render() {
return (
// more code
<a href="#" onClick={() => this.onClickPlus(parent)} className={this.state.classAdd}>
<i className="fa fa-plus"></i>
</a>
//more render code...
)
}
I don't know if this is the best practice, but works for me.

ReactJs: target.key undefined after method is reached from li rendered by map function

I'm currently trying to coding a react app that would do the following:
- Create a list of questions from an array using a map function.
- Making each list element clickable using a onClick prop
- The linked onClick method changes the state in another file with my 'qsChange' prop.
I had a hard time making my list clickable and finally managed following this question: React: trying to add an onClick to a li tag but the click handler function is undefined
However, now I cannot make it so that my variable 'choice' returns a defined value. I would want var choice to be equal to "A ?", "B ?" or "C ?" depending on which I click.
Here's my code:
var questions = ["A ?", "B ?", "C ?"];
var Questions = React.createClass({
handleClick: function() {
var visibility;
if(this.props.visibility) {
document.getElementById('second').style.display = 'none';
visibility = false;
this.props.onChange(visibility);
} else {
document.getElementById('second').style.display = 'block';
visibility = true;
this.props.onChange(visibility);
}
},
/* Here is where my problem lies */
onItemClick: function(e){
var choice = e.target.key;
this.props.qsChange(choice);
alert(choice);
},
render: function() {
return (
<div className="bigqs">
<div id="first" className="small" style={firstStyle}>
<h1>Question :</h1>
<button style={btnStyle} onClick={this.handleClick}>
<img id="arrow" src="../../img/arrow.png" />
</button>
<h3 id="selectedQuestion">{this.props.selected}</h3>
</div>
<div id="second" className="small" style={{display: 'none'}}>
<h4>
<ul>
{questions.map(function(qs, i) {return <li key={qs[i]} onClick={this.onItemClick}>{qs}</li>;}, this)}
</ul>
</h4>
</div>
</div>
);
}
});
I am still a newbie, so please be indulgent ;-)
I hope I was clear enough.
Ps: I have also tried this guide but it didn't work for me: http://derpturkey.com/react-pass-value-with-onclick/
Instead of grabbing the question from target, you can pass question through to your handler. Also, since inside map qs is a string, qs[i] will be getting the character in the string from that index. You just need to make sure your key is unique.
onItemClick: function(choice) {
this.props.qsChange(choice)
alert(choice)
},
render() {
return (
<div>
...
{questions.map(qs =>
<li key={qs} onClick={() => this.onItemClick(qs)}>{qs}</li>
)}
...
</div>
)
}
In fact, your intermediate function isn't doing much, you can just call your props function inside render:
render() {
return (
<div>
...
{questions.map(qs =>
<li key={qs} onClick={() => this.props.qsChange(qs)}>{qs}</li>
)}
...
</div>
)
}

Child Component is not able to trigger state change

Simple React State Example. The parent component is App which starts out just showing a button, when the button is clicked it should render AllRecipes (this works and I am able to manage state of AllRecipes). Inside AllRecipes is a button which needs to trigger a state change to then further render ingredients (this button does nothing when clicked, it needs to toggle the state of ingredients). I think this is a really good small example of how to manage state but I am missing something..
var App = React.createClass({
getInitialState: function(){
return {showIngredients: false, showRecipes: false};
},
toggleRecipes: function(){
this.setState({showRecipes: !this.state.showRecipes})
},
toggleIngredients: function(){
this.setState({showRecipes: !this.state.showRecipes})
},
render: function() {
var recipes = this.state.showRecipes ? <Recipes/> : null;
return (
<div>
<h1> Recipe App </h1>
<button onClick={this.toggleRecipes}> Show Recipes </button>
{recipes}
</div>
);
}
});
var Recipes = React.createClass({
render: function() {
var ingredients = this.props.showIngredients ? <Ingredients/> : null;
return (
<div>
<h1> list of recipes </h1>
<ul>
<li> Chicken Soup </li>
<li> Chicken Wings </li>
<button onClick={this.props.toggleIngredients}> Show Recipes </button>
{ingredients}
</ul>
</div>
);
}
});
var Ingredients = React.createClass({
render: function() {
return (
<div>
<h1> List of Ingredients </h1>
<ul>
<li> Salt </li>
<li> Pepper </li>
</ul>
</div>
);
}
});
React.render(<App/>, document.body);
It looks like you aren't passing toggleIngredients to Recipes. Try changing
var recipes = this.state.showRecipes ? <Recipes/> : null;
to
var recipes = this.state.showRecipes ? <Recipes toggleIngredients={this.toggleIngredients} /> : null;

Categories