React handle click in reusable stateless component when condition is true - reactjs

I have on component which is stateless and it is used in both parent component
<div onClick={() => handleClick()}><div>
I have to add handle click function but only for one of them. I have one bool variable which is responsible for that e.g. shouldHandleClick.
So I need to write something like but it works for cases with props, strings etc. etc.
<div {shouldHandleClick ? onClick={() => handleClick()} : null}><div>
Do you have any ideas otherwise i will handle click in the second component which doesn`t need this handle click function

<div onClick={this.props.shouldHandleClick ? this.handleClick : null}><div>
And send shouldHandleClick with props to activate or deactivate click function.

It looks like you are almost there:
<div onClick={shouldHandleClick ? handleClick : null}></div>

Related

react limits the number of renders

in react I am displaying products I.E.
{renderPosts.map((item, index) => (
...
now, in each product, there is a button to delete that product, inside a button I have onclick that calls sweetAlert to delete particular product:
<Button
color="danger"
simple
justIcon
onClick={warningWithConfirmMessage}
>
Everything works fine like that... but if I want to pass ID of the product that has to be deleted...
<Button
color="danger"
simple
justIcon
onClick={warningWithConfirmMessage(item.postId)}
>
Now I am having error:
Too many re-renders. React limits the number of renders to prevent an infinite loop.
How I can pass anything to function... anybody
Thanks in advance!
The new onClick handler you're passing is calling the warningWithConfirmMessage every time it renders. To pass the function as a handler function instead of calling it, use:
onClick={() => warningWithConfirmMessage(item.postId)}

React onClick on stateless component

I have been trying to fire an onClick on a react component. The event fires if I use
<button onClick={()=>this.goToPage('next')}>Next Page</button>
If I use the same method on a stateless component, it doesn't fire:
<PageButton onClick={()=>this.goToPage('next')}>Next Page</PageButton>
Why this is not possible?
Because what you are defining is a custom component. Note, that everything that you provide to the custom component is considered as props. So, your onClick method is also provided as props. Essentially you'll be required to do -
<PageButton onClick={()=>this.goToPage('next')}>Next Page</PageButton>
and in your <PageButton /> component -
<button onClick={this.props.onClick}>Next Page</button>
if you know what props you are providing to this component and not providing any unnecessary props, you can even spread the props object, like -
<button {...this.props}>Next Page</button>
Note - If you have other props to provide to this component as well, kindly refrain from using this method, as this will result in many unrecognized function warnings.
PS: Even if you write
<PageButton style={{backgroundColor: 'red}}>Next Page</PageButton>
it won't work because, this is treated as a prop. You'll need to handle the style prop in the render method of this <PageButton/> component
This does not work on a stateless component because the onClick is considered as a prop rather a event listener , you should implement.
For example inside PageButton you should implement something like this
render(){
return <div onClick={()=>this.props.onClick('next')}/>
}

How to replace a component with another one upon event (button click) in react js

I have a long list of data display divided into blocks with an edit button on side of each block, like this:
Whenever the edit button is clicked, i need to replace the display component with edit component, replacing the text with form like this
what would be the best way to do this.
I have tried putting the components inside state as list and replacing Display component with Form Component, when Edit is clicked
so instead of returning this from render():
return(
<Display />
);
Now i am returning:
return(
{this.state.components[0]}
);
and when button is clicked doing this
this.setState({components:[<EditForm />]})
It works but i was wondering is storing Component and JSX inside state a good idea/ professional practice?
you could do something like this:
use a variable in state for knowing edit is clicked or not
state={
isEdit:false,
}
on click of edit:
this.setState({isEdit:true})
in render() use conditional rendering:
render(){
return(
<div>
{(!this.state.isEdit) ? <Display /> : <EditForm />}
</div>
)
}
I would hold in state just a Boolean for showing the edit form or the display and toggle this on button click.
Then in you render method just a simple if statement to choose what to render e.g.
render() {
if (this.state.edit) return <EditForm />
return <Display />
}

React: Hiding/Showing an element while hiding the rest of the similar elements

I have a recipe creator that creates recipes and also lists their ingredients. I want it to only show the Recipe name and it's div it's inside of, but when you click it, it reveals the ingredients section. If any other sections are open I want it to also close them.
I've tried a couple solutions with state but haven't come up with a solid solution. I could probably do it with jQuery but I've heard it's not good practice to use React and jQuery so I'd rather do it properly.
This is the full app: https://github.com/jeffm64/recipe-box2/tree/master/src/components
The recipe boxes are rendered through .map in the main app render function as shown here:
{Recipes.map(function(item, key) {
return <RecipeBox recipe={Recipes} name={item.name} ingredients={item.ingredients} order={item.order} key={key} generalUpdate={genUpdate} />;
})}
Revealing just the one component's ingredients will be easier. Closing the rest will be a little trickier.
Revealing ingredients - Without Redux, you could add a state property isOpen. When you click on a button in that component it should change the state property isOpen to true. Hide/show the ingredients based on that state property value, which you can do in the markup (shown below) or with a class and a CSS rule.
<div key={1}>
showIngredients = () => { this.setState({isOpen: true}) }
<button onClick={this.showIngredients}>Show ingredients</button>
{this.state.isOpen && <div>Ingredients list</div>}
</div>
Hiding other ingredients - This is a bit trickier and will require a different kind of solution. You'll need to define a method in a parent component that sets the state of all child components. Note the key in the component above. If each child has a unique key, and the parent defines a state property of selectedKey, you could do something like this:
// parent
revealChild = (key) => {this.setState(selectedKey: key)}
...
<div>
{children.map((child) => {
return <Child onReveal={this.revealChild} key={child.key} isSelected={this.state.selectedKey == child.key}/>
})}
</div>
// child
handleReveal = () => this.props.onReveal(this.props.key)
showIngredientsClass = () => this.props.isSelected ? 'visible' : 'hidden'
showButtonClass = () => this.props.isSelected ? 'hidden' : 'visible'
...
<button onClick={handleReveal} className={this.showButtonClass()}>Show ingredients</button>
<div className={this.showIngredientsClass()}>
My ingredients
</div>

Can I pass the selected tab back from onTouchTap event of Material-UI Tabs component?

I'm using the Material-UI Tabs component in my ReactJS app.
I'm handling the onTouchTap event of the Tabs component. I'd like to pass the currently selected tab back as a parameter to the event handler.
Is this possible?
So something like this
<Tabs onChange={props.onChangePosition}
onTouchTap={e => {/* What */}>
I know that the onChange handler returns it, but I'd like to use onTouchTap in this instance.
Yes, this can be done. You need to capture a "ref" to your Tabs control, and then call getSelectedIndex() on it, inside your onTouchTap. getSelectedIndex is somewhat internal, so it has an unexpected method signature in that you must also pass it in its own props.
<Tabs
ref={ref => (this.tabs = ref)}
onTouchTap={(e) => console.log(this.tabs.getSelectedIndex(this.tabs.props))}
>
...

Resources