Passing function and params through react props - javascript

I have an dropdown menu with buttons for the dropdown elements and pressing them causes an fucntion call.
`
<div className = "dropdown-container">
<button className = "dropdown-button"> Sort </button>
<div className = "dropdown-content">
<button className = "sort-button" onClick={() => changeFilter(['sort=-Covered_distance'])}> Furthest </button>
<button className = "sort-button" onClick={() => changeFilter(['sort=+Covered_distance'])}> Shortest </button>
<button className = "sort-button" onClick={() => changeFilter(['sort=-Duration'])}> Longest </button>
<button className = "sort-button" onClick={() => changeFilter(['sort=+Duration'])}> Fastest </button>
</div>
</div>
Im trying to clean up my code as I have multiple dropdown menus next to each other with the same principle. I thought about making a react component that has the structure of the dropdown menu but as I have an function call in it I need to pass this through also so like.
<div className = "filters-container">
<Dropdown changeFilter = { () => changeFilter() }/>
</div>
Now this works as it calls the function changeFilter(), but none of the params from the other component gets called with the call so it basically calls only changeFilter(), when I press any of the buttons. How can I get the params with the call?

You must pass the argument in the changeFilter prop.
For example:
<div className="filters-container">
<Dropdown changeFilter={() => changeFilter(['sort=-Covered_distance'])} />
</div>
Here's a working example:
https://codesandbox.io/s/falling-currying-kd0oco?file=/src/App.js
The problem here is that when you pass a function as a prop, you can't change their parameters inside the component, the parameter has to be passed from the parent.

Pass the paramter ['sort=-Covered_distance'] in changeFilter function like this:
<div className = "filters-container">
<Dropdown changeFilter={() => changeFilter(['sort=-Covered_distance'])} />
</div

Related

how can i get my button to disappear? in reactjs

i am trying to make my button disappear if my textarea is empty
until now i have made some code for it but i still cant do it
in the code i am trying to make the css dynamic by having it change accoring to some ternery condition id the condition is met the css will allow the button to work and if not the other css class will turn the button off
my problem is that i want the on/off condition to work only when the textfield has more than one letter ( is not empty ) this will help me in my posting application as it will not post any empty posts instead only posts with letters and words ( non empty textarea) will post
here is the code:
function PostingNow() {
const [post, setPost] = useContext(Mycontext);
const tw = useRef('')
const[count,setCount] = useState(false)
return (
<div >
<textarea placeholder='whats up?' className="box" ref={tw}></textarea>
<button className={count?'tweetbutton':'unclickable'} >
Tweet
</button>
</div>
{post.map((post, i) => (
<Postingcomponent name ='user name'image={Photo} key={i} postContent={post}/>
))}
</div>
);
}
export default PostingNow
You can conditionally render your button in the jsx.
First make your textarea a controlled component so you have access to its state.
Then write
{textAreaText && <button ... />}
Make the textarea to be a controlled input
const [textarea, setTextarea] = useState("")
...
<textarea onChange={e => setTextarea(e.target.value)}>{textarea}</textarea>
Then for the button:
{textarea && <button ... />}
For better UX, it's recommended to disable the button instead of removing it from DOM.
<button disabled={!textarea} ... />
If you make the TEXTAREA tag something like:
<textarea placeholder='whats up?' className="box" ref={tw} class='unclickable'
onkeyup="fixPostButton(this, 'postButton', 'unclickable', 'tweetbutton');">
And make the BUTTON:
<button id="postButton" class="unclickable">Tweet</button>
Then this javascript will change the class after each keystroke:
<script>
function fixPostButton(txta, butn, isempty, notempty) {
var classX = (txta.value == '') ? isempty : notempty ;
document.getElementById(butn).className = classX; }
</script>

Get key of mapped child component from parent function

I have a child navigation component and i'm trying to get the key of the selected item in the parent component to update my state to the selected nav item. I'm using a map in the child component and I cant seem to pass the key of the selected item back up to the parent item to set the state. here are my components
Parent
** my function to set the nav item **
let navPress = async key => {
let selNavItem = await navItems.find(object => {
return object.key === key
});
setActiveNavItem(selNavItem.key)
}
** return for parent component **
return(
<ProjectDetailNav
navItems={navItems}
activeNavItem={activeNavItem}
onClick={() => navPress}
/>
)
Child component (nav) with map function
<div id='nav-container'>
{props.navItems.map(navItem => {
if (navItem.key === props.activeNavItem) {
// console.log(navItem.key)
return (
<button className='active-nav-item' key={navItem.key} onClick={props.onClick(navItem.key)}>
<img className='nav-item-icon' src={navItem.icon} />
<h6 className='nav-item-title'>{navItem.title}</h6>
</button>
)
} else {
return (
<button className='nav-item' key={navItem.key} onClick={props.onClick(navItem.key)}>
<img className='nav-item-icon' src={navItem.icon} />
<h6 className='nav-item-title'>{navItem.title}</h6>
</button>
)
}
})}
</div >
By onClick={props.onClick(navItem.key)} you are assigning the return value of props.onClick to buttons click event calling it immediately on render. It should be wrapped in a function.
<button
className="active-nav-item"
key={navItem.key}
onClick={() => props.onClick(navItem.key)}
>
<img className="nav-item-icon" src={navItem.icon} />
<h6 className="nav-item-title">{navItem.title}</h6>
</button>
This way when onClick event is fired, the anonymous function will be called which will call props.onClick(navItem.key).

OnClick function not working with custom button Component

I am passing the value of the button the user clicks on to an array with the following function.
const [pizzaSize, setPizzaSize] = useState("Choose your Pizza Size");
const [startPrice, setStartPrice] = useState(0);
const addPizza = (e) => {
setPizzaSize(e.target.name);
setStartPrice(parseInt(e.target.value));
};
I want to use a custom button component in order to have it toggle on and off, like I have already done with other buttons on the same page.
const ButtonClickable3 = (props) => {
const [isActive, setActive] = useState("false");
const handleToggle = (e) => {
setActive(!isActive);
props.onClick(e)
};
return <button
type="button"
value={props.value}
className={isActive ? "button btn fourth" : "button btn fourthActive"}
onClick={handleToggle}
>
{props.name}
</button>
}
Finally I call the function as follows
<ButtonClickable3 name="test" value="5" onClick={(event) => addPizza(event)}></ButtonClickable3>
When I use a regular button the function works, so I am stumped as to why the custom one does not.
My custom buttons 1 and 2 are also working, but they are using a different function.
I have put my full code on a codesandbox here.
I thank you in advance for your help.
Your original <button has a name attribute, but the <ButtonClickable3 does not. so:
setPizzaSize(e.target.name);
fails with the ButtonClickable3. You need:
return <button
type="button"
name={props.name}
value={props.value}
inside ButtonClickable3.

Having multiple buttons call a function in ReactJS

Sorry if the title is vague. My problem is that I have three button tags, and for each tag I want it to send a unique argument to selectSupplier(). However no matter what button I press selectSupplier() only receives the last value ("ultramar") as an argument.
selectSupplier(supplier){
this.props.Obj.supplier = supplier
}
render() {
//console.log("SUPPLIER", this.props)
return (
<div>
<button onClick={this.showMenu}>
Select Supplier
</button>
{
this.state.showMenu
? (
<div
className="menu"
ref={(element) => {
this.dropdownMenu = element;
}}
>
<button value="Husky" onClick={this.selectSupplier("Husky")}> Husky </button>
<button value="Shell" onClick={this.selectSupplier("Shell")}> Shell </button>
<button value="Ultramar" onClick={this.selectSupplier("Ultramar")}> Ultramar</button>
</div>
)
: (
null
)
}
</div>
);
You can call like this :
this.selectSupplier.bind(this,"Husky");

React component with two sets of children

I'm creating a component that needs to take in two sets of children and to be placed in two different parts of a component.
let CreditCardForm = ({icons, fields}) => (
<div>
<div className='some'>
<div className='special'>
<div className='nesting'>
{icons}
</div>
</div>
</div>
{fields}
</div>
)
let CreditCardFormUsage = () => {
let icons = () => (
<Icons>
<IconBogus/>
<IconVisa/>
<IconPaypal/>
<IconMore/>
</Icons>
)
let fields = () => (
<CreditCardFields>
<FieldCardNumber/>
<FieldName/>
<FieldExpirey/>
<FieldCCV/>
</CreditCardFields>
)
return (
<CreditCardForm icons={icons} fields={fields}/>
)
}
The code above should work, my question is it possible to grab those property values based on the children in the element itself, and have something more natural?
<CreditCardForm>
<Icons>
<IconBogus/>
<IconVisa/>
<IconPaypal/>
<IconMore/>
</Icons>
<CreditCardFields>
<FieldCardNumber/>
<FieldName/>
<FieldExpirey/>
<FieldCCV/>
</CreditCardFields>
</CreditCardForm>
Yes, this.props.children will return an array so if you always want to load specific children, then just reference those children by index in your wrapper. Then you could just turn icons and fields into wrapper components. Here is a working jsfiddle. See how the render method of App is exactly what you want.
CreditCardForm render:
<div>
<div className='some'>
<div className='special'>
<div className='nesting'>
{this.props.children[0]}
</div>
</div>
</div>
{this.props.children[1]}
</div>
Fields and Icons render:
<div>{this.props.children}</div>
App render:
<CreditCardForm>
<Icons>
<IconBogus />
</Icons>
<Fields>
<FieldCardNumber />
<FieldName />
</Fields>
</CreditCardForm>
yes, you can do it with child props. Read more #docs:
https://facebook.github.io/react/tips/children-props-type.html
And of course check out React.Children
https://facebook.github.io/react/docs/top-level-api.html#react.children

Categories

Resources