I am using Ant design and they have a component called Switch, Switch have a custom event handler
import "./styles.css";
import "antd/dist/antd.css";
import { Switch } from "antd";
import { useState } from "react";
export default function App() {
const [status, setStatus] = useState(true);
const handleChange = (e) => {
// e is a boolean variable, true or false
console.log(e);
setStatus(e);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<Switch checked={status} onChange={handleChange}></Switch>
</div>
);
}
and I have so much of question about that kind of syntax
Does
onChange={handleChange}
is equivalent with
onChange={(e) => handleChange(e)}
If for some reason, I can only write
onChange={handleChange}
how can I pass the real event handler to handleChange to do some stopPropagation, some thing likes
const handleChange = (e, reale) => {
reale.stopPropagation()
setStatus(e);
};
Simple codesandbox to understand what I said.
Does
onChange={handleChange}
is equivalent with
onChange={(e) => handleChange(e)}
They're equivalent if and only if the function receives one argument. But for ant design switches, the onChange actually passes in two parameters: the new value, and the event object. So if you want to create a new function and then call handleChange in that function, you'll probably want to pass both parameters through:
onChange={(value, e) => handleChange(value, e)}
You can write thing something like
onChange={(e) => handleChange(e, reale)}
Related
This question already has an answer here:
ReactJS, event.currentTarget doesn't have the same behavior as Vanilla Javascript
(1 answer)
Closed last month.
I want to capture the name attribute of a button on click in React.
I tried the following code block:
export function TestButton(props){
function logName() {
console.log(this.name)
}
return(
<button name={props.name} onClick={event => logName(event.currentTarget.getAttribute("name"))} type='button'>{props.text}</button>
)
}
My expectation was that this code would allow me to create a button that displays the name in the console log:
<TestButton name='helloWorld' text='Click Me'/>
Instead I get an alert that this is undefined. This is in spite of my ability to see the name when I inspect the element.
I have also tried target instead of currentTarget with no luck. I also tried event.currentTarget.name without the results I desire.
What did i miss?
In react, I believe this is reserved for classes, whereas you are defining a functional component. In a functional component, the comparable state value would be stored with useState(). That being said, I'm not sure I see the need for that here, since this button is getting its props from somewhere and the value of name and text are not changing in this component. I would code it this way:
export const TestButton = ({props}) => {
return(
<button name={props.name} onClick={() => console.log(props.name)}>
{props.text}
</button>
)
}
Now to go a bit further, maybe you want to use state wherever this button is being rendered. That could look like this:
import {TestButton} from "./someFile";
const [name, setName] = useState("some-button");
const [text, setText] = useState("click me!");
// now there could be some code here that decides what the name or text would be
// and updates the values of each with setName("name") and setText("text")
const Page = () => (
<>
<TestButton props={{name: name, text: text}} />
</>
)
This is all building off your current code, but now I will combine everything in a way that makes sense to me:
import {useState} from "react";
const [name, setName] = useState("some-button");
const [text, setText] = useState("click me!");
// some code to determine/change the value of the state vars if necessary
const TestButton = ({name, text}) => {
return(
<button name={name} onClick={() => console.log(name)}>
{text}
</button>
)
}
export const Page = () => (
<>
<TestButton name={name} text={text} />
</>
)
Pleas try as follows:
export function TestButton(props){
function logName() {
console.log(props.name)
}
return(
<button name={props.name} onClick={() => logName()} type='button'>{props.text}</button>
)
}
Try this
export function TestButton(props){
const logName = (e, name) => {
console.log("name attribute ->", name)
}
return(
<button name={props.name} onClick={ (e) => logName(e, props.name)} type='button'>{props.text}</button>
)
}
I have an input with an onChange attribute and an onKeyDown attribute. The onChange attribute receives a value of {(e) => props.change(e)} and in the parent component I assign the change prop to a handleChange function. I want to do the same thing with my onKeyDown attribute, however I face two issues:
When I use {(e) => props.key(e)}, Chrome Devtools says that key is not a prop. When I try passing {key} instead of (props) to the child component, Chrome Devtools says that key is not a function.
I'm trying to pass the prop so that I can consume the key code value in the parent component and execute some logic.
I've also tested to make sure the function is working within Home.js. If someone could give a solution and an explanation as to why this happens I would be appreciative.
Here is an example of my code:
/ App.js
export default function App() {
const key = (e) => {
if (e.keyCode === 8) {
...
}
}
const change = (e) => {
return ...
}
return
<Home
key={key}
change={change}
/>
}
/ Home.js
export default function Home(props) {
return
<input
onChange={(e) => props.change(e)}
onKeyDown={(e) => props.key(e)}
/>
}
key is a special prop in React and gets special treatment:
[…] there are two special props (ref and key) which are used by React, and are thus not forwarded to the component.
So it should work if you change the name of the prop:
App.js
export default function App() {
// …
return
<Home
myKey={key}
change={change}
/>
}
Home.js
export default function Home(props) {
return
<input
onChange={(e) => props.change(e)}
onKeyDown={(e) => props.myKey(e)}
/>
}
I know that react component will render everytime state changes and useCallBack memorize function depending on the dependency array provided.
But If I have this:
<input type="text" name="name" value={values.name} onChange={handleChange} />
<input type="text" name="phone" value={values.phone} onChange={handleChange} />
Whats the difference between these two handleChange implementation?
const handleChange = e => {
setValues(values => ({ ...values, [e.target.name]: e.target.value }))
}
and
const handleChange = useCallback(e => {
setValues(values => ({ ...values, [e.target.name]: e.target.value }))
}), [])
Code snippet needed in comment
const Child = () => {
console.log("Child rerendered");
return <div>Hello World </div>;
};
export default function App() {
const [count, setCount] = useState(0);
console.log("Parent rerendered");
return (
<div className="App">
<Child />
<button
onClick={() => {
setCount((x) => x + 1);
}}
>
{count}
</button>
</div>
);
}
The difference is that with the second one using useCallback, you'll keep using the first handleChange function you create; with the first one where you don't use useCallback, you're creating a new handler function each time. (Technically, you create a new one every time in both cases, but useCallback will only return the first one that gets created, because you've provided an empty dependency array.) More in the documentation.
It doesn't matter much when giving the handler function to input or other native HTML elements, or even simple components. If you were providing this handler function to a complex component, it might be better to use useCallback if that complex component optimizes re-rendering (for instance, with React.memo, PureComponent, or shouldComponentUpdate).
I want to have access to the value of a textField in another module in reactjs. The module that wants to have access does not import the whole textfield but only needs access to the value. What is the best way to access the value variable in another module in reactjs?
Here is my functional textField component:
export default function textField(props) {
const [value, setValue] = React.useState("");
const handleChange = (event) => {
setValue(value);
};
return (
<div>
<TextField
id="outlined-multiline-static"
label="Frage"
multiline
onClick={handleClickOpen}
rows={4}
value={value}
placeholder="hello"
variant="outlined"
style={{
backgroundColor: "white",
}}
/>
</div>
);
}
You can send onTextFieldChange function as props whenever textField's value changes you can pass a value to onTextFieldChange function and you can use it in the parent component.
There is an alternate way, Redux
You should try to use redux for the shared state between components which are either not related directly(i.e. sibling components or have a lengthy hierarchy). For small applications, redux is overkilled so should be avoided.
The most likely option that comes to mind here is the concept of lifting state, in which the nearest ancestor component has some means by which it also keeps track of the state, and the passes it into the sibling that needs to track it. You could make this an optional feature of your module by allowing a onChangeCallback prop that is called on each change; this prop could then be passed a setSharedState hook that would set the state on the ancestor:
const ParentComponent = () => {
const [textfieldVal, setTextfieldVal] = useState();
return (
<TextField onChangeCallback={setTextFieldVal} />
);
}
And you update your module to something like:
export default function textField(props) {
const [value, setValue] = React.useState("");
const {onChangeCallback} = props;
const handleChange = (event) => {
setValue(value);
if (typeof onChangeCallback === 'function') {
onChangeCallback(event); // or value, I'm not sure which you should be using here, this might be incorrect
}
};
return (
<div>
<TextField
id="outlined-multiline-static"
label="Frage"
multiline
onClick={handleClickOpen}
rows={4}
value={value}
placeholder="hello"
variant="outlined"
style={{
backgroundColor: "white",
}}
/>
</div>
);
}
This is just a rough example. Other options for passing around state freely would be using Redux or the Context API, but the former might be overkill for this one case and the latter probably not a great fit for a specific, single-use datapoint.
there are may option but the proper option in pass as props
const modle1= () => {
const [textfieldVal, setTextfieldVal] = useState();
return (
<TextField onChangeCallback={setTextFieldVal} />
);
}
export default function textField(props) {
const [value, setValue] = React.useState("");
const {onChangeCallback} = props;
const handleChange = (event) => {
setValue(value);
if (typeof onChangeCallback === 'function') {
onChangeCallback(event); // or value, I'm not sure which you should be using here, this might be incorrect
}
};
return (
<div>
<TextField
id="outlined-multiline-static"
label="Frage"
multiline
onClick={handleClickOpen}
rows={4}
value={value}
placeholder="hello"
variant="outlined"
style={{
backgroundColor: "white",
}}
/>
</div>
);
}
or you can use create context and use context and provide the parent to provide and the child as a consumer but the best option pass as a prop
I would recommend you use the parent-child nature of react in order to handle this. Since I'm not sure the relationship between the other module and this module, I'll provide a rough skeleton.
In a parent component:
export default function ParentComponent(){
const [status, updateStatus] = useState("")
return(
<TextView updateParent={updateStatus}>
</TextView>
)
}
Then in your child component:
const handleChange = (event) => {
setValue(value);
props.updateParent(value);
};
If they are siblings, I would use a parent component and then pass the state down to the sibling. Otherwise, as appropriate, use this parent child relationship to pass and update state.
HTH
I'm making kind of a search input that, when pressing enter, it should be able to execute a function written in its prop onEnter, but I don't understand how I could approach it.
Code:
import React, {useState} from "react";
import { t as typy } from "typy";
export type Props = {
name?: String,
imgSrc?: String,
alt?: String,
onEnter?: function
};
export const SearchInput = ( {name, imgSrc, alt, onEnter}: Props ) => {
const [searchText, setSearchText] = useState('');
return(
<React.Fragment>
<button className='input-search-mobile' onClick={typy(onEnter).safeFunction}>
<img src={typy(imgSrc).safeString} alt={typy(alt).safeString}/>
</button>
<div className='input-search'>
<img className='input-search-icon' src={ typy(imgSrc).safeString} alt={typy(alt).safeString} />
<div className='input-search-divider'></div>
<input type="text" name={name} onKeyPress={
(e) => {
if(e.key == 'Enter'){
{onEnter(searchText)}
}}
} onChange={event => setSearchText(event.target.value)}/>
</div>
</React.Fragment>
);
}
export default SearchInput;
Component with props:
<SearchInput imgSrc={lupa} onEnter={() => {*I need to get the value of searchText somehow*} />
Looking at your code snippet for SearchInput, it seems you forgot to pass the value in your onEnter callback function.
Try doing this: onEnter={(val) => console.log(val)}