Correct typing for your Hamburger functional component is:
function Hamburger({ onClick }: { onClick? : React.MouseEventHandler }): JSX.Element {
// actual code
}
As number of props grow, inline type declarations may get messy. So, it's a good habit to move them into designated type:
type Props = {
onClick?: React.MouseEventHandler
}
function Hamburger({ onClick }: Props) JSX.Element {
// actual code
}
It also has benefits if later you'll have to accept children prop in this component. Then you may use React.FC helper with Props type:
const Hamburger: React.FC<Props> = ({ onClick, children }) => { // no need to type `children` prop yourself
// actual code
}
Answer from aleksxor on Stack OverflowCorrect typing for your Hamburger functional component is:
function Hamburger({ onClick }: { onClick? : React.MouseEventHandler }): JSX.Element {
// actual code
}
As number of props grow, inline type declarations may get messy. So, it's a good habit to move them into designated type:
type Props = {
onClick?: React.MouseEventHandler
}
function Hamburger({ onClick }: Props) JSX.Element {
// actual code
}
It also has benefits if later you'll have to accept children prop in this component. Then you may use React.FC helper with Props type:
const Hamburger: React.FC<Props> = ({ onClick, children }) => { // no need to type `children` prop yourself
// actual code
}
import { forwardRef } from "react";
import { Box } from "@chakra-ui/react";
import { HiOutlineMenu } from "react-icons/hi";
type THamburgerProps = React.ComponentPropsWithoutRef<"button">;
const Hamburger = forwardRef<HTMLButtonElement, THamburgerProps>(
({ ...props }, ref) => {
return (
<Box
as="button"
ref={ref}
type="button"
p="1"
fontSize="2xl"
color="gray.600"
display={{ base: "block", lg: "none" }}
{...props}
>
<HiOutlineMenu />
</Box>
);
}
);
Hamburger.displayName = "Hamburger";
function App() {
return <Hamburger onClick={() => console.log("hamburger clicked!")} />;
}
Best way to pass onClick, children, and similar ReactNode attributes as props to component?
javascript - React Typescript: Passing onClick as a Prop
React passing onClick as props to sub components required?
Help passing object through onClick of component.
You could try onClick={() => props.soundDisplayChange(x.sound)}
More on reddit.comI am currently working on creating a card component with various interactions. I want to have an interface to represent the data model of the card, but I don't want to have to add dummy values for onClick and such.
Is the following an acceptable approach? Or is there a much better way to do this? Thank you.
https://ibb.co/7RmKRC1
Correct typing for your Hamburger functional component is:
function Hamburger({ onClick }: { onClick? : React.MouseEventHandler }): JSX.Element {
// actual code
}
As number of props grow, inline type declarations may get messy. So, it's a good habit to move them into designated type:
type Props = {
onClick?: React.MouseEventHandler
}
function Hamburger({ onClick }: Props) JSX.Element {
// actual code
}
It also has benefits if later you'll have to accept children prop in this component. Then you may use React.FC helper with Props type:
const Hamburger: React.FC<Props> = ({ onClick, children }) => { // no need to type `children` prop yourself
// actual code
}
import { forwardRef } from "react";
import { Box } from "@chakra-ui/react";
import { HiOutlineMenu } from "react-icons/hi";
type THamburgerProps = React.ComponentPropsWithoutRef<"button">;
const Hamburger = forwardRef<HTMLButtonElement, THamburgerProps>(
({ ...props }, ref) => {
return (
<Box
as="button"
ref={ref}
type="button"
p="1"
fontSize="2xl"
color="gray.600"
display={{ base: "block", lg: "none" }}
{...props}
>
<HiOutlineMenu />
</Box>
);
}
);
Hamburger.displayName = "Hamburger";
function App() {
return <Hamburger onClick={() => console.log("hamburger clicked!")} />;
}
The reason is that the LinkButton component you created is just a javascript object, not a DOM node, so it does not have event handlers like onClick. The button element is transformed into the actual DOM element so it will have all the associated event handlers that the actual HTML element.
When you add an onClick prop to the LinkButton component, it is just a property of an object. By calling props.onClick from inside of that component you are just calling a function that is stored inside of a property, similar to this:
let props = {
onClick: function () { alert("Executed!"); }
};
props.onClick();
Hope this helps you!
In your first example, you are not actually adding the onClick event. Just passing the reference to the component doesn't mean it automatically know what to do with it.
The second example does actually add the onClick to the button, like it should, which is why it works.
In your first example, you are using "onClick" as a parameter, not as the actual event handler.
I have a component that builds a series of buttons for a drum machine I am working on. My component:
const FormGrid = (props) =>{
return(
<div id='button-grid'>{props.array.map(x=>
<button key={x.letter.toString()} id={x.letter} onClick=
{props.soundDisplayChange}>{x.letter}</button>
)}
</div>
)
}I would like to pass parts of my x variable into the onClick function. Is there a way to do this? My object looks like:
[{letter:'Q',sound: 'https:'},{letter:'W',sound: 'https:'}]Is there a way to pass x or pass x.sound through the onClick?
You could try onClick={() => props.soundDisplayChange(x.sound)}
import React, { Component } from "react";
class FormGrid extends Component {
getClickHandler = item => event => {
const { soundDisplayChange } = this.props;
soundDisplayChange(item);
};
render() {
const { array } = this.props;
return (
<div id="button-grid">
{array.map(item => (
<button
key={item.letter.toString()}
id={item.letter}
onClick={this.getClickHandler(item)}
>
{item.letter}
</button>
))}
</div>
);
}
}
export default FormGrid;
I hope this helps. It's just a really verbose way of saying the same thing that u/ansella said, but I thought it might make the bigger picture more clear.
For functions like onClick, you have to describe input arugments and output or just write Function (although for better type checking you shouldn't just write Function).
So something like this:
onClick: () => void
If for example your function gets a number and returns a string, you should write it like this:
onClick: (n: number) => string
Parent Component:
interface OnClickIdInterface {
(): void,
}
export interface parentPropsInterface {
onClick?: OnGetIdInterface;
}
render() {
return <ChildComponent onClick={(id) => this.onClick(id)}/>
}
Child Component:
const HomePresentation: React.FunctionComponent<parentPropsInterface> = ({onClick}) => {
return (
<div onClick={()=>onClick()}>
some content
</div>
)
}
Hello all, I went through and completed this tutorial, a tic tac toe game, in which the final state of the code can be found here. What I don't understand are the differences in the onClick functions when we're creating the game, board, and square. For example:
Within the Game's render method, when we create the board we pass the prop "onClick={i => this.handClick(i)}". When the board is clicked, where is this parameter i coming from? As in, what is supplying it?
Within the Board's renderSquare method, when we create the Square, the onClick prop we supply is "{() => this.props.onClick(i)}", why does it not take a parameter now?
Lastly, within the Square function, we return a square whose onClick looks very different from the others, simply "props.onClick". The tutorial mentions "note the missing parenthesis" but doesn't explain why.
So basically I'd like to understand why in some cases we use "(i) =>" and in others we use "() =>" and finally, why sometimes we don't use arrow functions at all.
The interface with props should be
interface IProps_Square {
message: string;
onClick: React.MouseEventHandler<HTMLButtonElement>;
}
Notice also that if you use semicolons, the interface items separator is a semicolon, not a comma.
Another hint: I recommend type rather than interface for props. They are almost the same, the only difference I found is that interface may be extended anywhere in the code, in fact it is used for globals.
Is there a way to replace the 'any' keyword in the IProps_Square interface with an explicit function signature
I would just () => void i.e. a function that takes no arguments and you don't care if it returns anything.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
interface IProps_Square {
message: string,
onClick: () => void,
}
class Square extends React.Component < IProps_Square > {
render() {
return (
<button onClick={this.props.onClick}>
{this.props.message}
</button>
);
}
}
class Game extends React.Component {
render() {
return (
<Square
message = { 'click this' }
onClick = { () => alert('hello') }
/>
);
}
}
ReactDOM.render(
<Game />,
document.getElementById('reactjs-tutorial')
);
However if you need the parameter the proper type for it is React.MouseEvent<HTMLElement>, so:
interface IProps_Square {
message: string,
onClick: (e: React.MouseEvent<HTMLElement>) => void,
}
Just combine your two props into one interface:
interface CloseButtonProps
{
className?: string
onClick: MouseEventHandler
}
const CloseButton = ({ className, onClick }: CloseButtonProps) =>
{
// However you plan on integrating className
}
export default CloseButton
interface CloseButtonProps {
className?: string;
onClick?: (e:React.MouseEvent<any>) => void;
/* You can add another props here */
}
const CloseButton = ({ className, onClick }: CloseButtonProps) => {
...
}