Having this code snippet:
const MyComponent = ({ e }) => {
const toggleButton = (e) => {
console.log('eee: ', e.target.value);
};
return (
<div>
<div>
<input className='input-search' type='text' placeholder='search' />
<Button onClick={(e) => toggleButton(e)}>reset</Button>
</div>
</div>
);
};
I was expecting to see in the log the value from input but it is undefined. Any thoughts?
e.target is the button which has no value attribute. You should be storing the input value in state with a onChange event. Make sure that the input's value attribute reflects the state, and use useEffect to log the changes to the console.
const {useState, useEffect} = React;
function Example() {
const [input, setInput] = useState('');
useEffect(() => {
console.log(`State: ${input}`);
}, [input])
function handleClick() {
setInput('');
}
function handleInput(e) {
const { target: { value } } = e;
setInput(value);
}
return (
<div>
<div>
<input onChange={handleInput} type="text" placeholder="search" value={input} />
<button onClick={handleClick}>reset</button>
</div>
</div>
);
};
// Render it
ReactDOM.render(
<Example />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Related
How can I use the value of state x in handleClick function to show an alert of input value in state x using Function component?
import React, { useState } from "react";
import "./App.css";
function About() {
const [state, setState] = useState({
x: "",
output: [],
});
//for onChange Event
const handleChnage = (e) => {
setState({ ...state, [state.x]: e.target.value });
console.log(e.target.value);
};
//for onClick Event
const handleClick = () => {
alert(state.x);
};
return (
<>
<h1>This is about about </h1>
<input
placeholder="Enter a number"
value={setState.x}
onChange={handleChnage}
/>
<button onClick={handleClick}>get Table</button>
</>
);
}
export default About;
It should be x instead of state.x
const handleChnage = (e) => {
setState({ ...state, x: e.target.value })
}
and the value should be state.x here instead of setState.x:
<input
placeholder="Enter a number"
value={state.x}
onChange={handleChnage}
/>
Remember on hooks, the first parameter is the value, the second parameter is the setter function.
Two issues should be fixed:
You do not need the computed value [state.x], it should be just x.
setState({ ...state, x: e.target.value });
The value for the input should be state.x not setState.x
<input
placeholder="Enter a number"
value={state.x}
onChange={handleChnage}
/>
function About() {
const [state, setState] = React.useState({
x: "",
output: []
});
//for onChange Event
const handleChnage = (e) => {
setState({ ...state, x: e.target.value });
console.log(e.target.value);
};
//for onClick Event
const handleClick = () => {
alert(state.x);
};
return (
<React.Fragment>
<h1>This is about about </h1>
<input
placeholder="Enter a number"
value={state.x}
onChange={handleChnage}
/>
<button onClick={handleClick}>get Table</button>
</React.Fragment>
);
}
ReactDOM.render(<About />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div class='react'></div>
I want to give some text in input field and after clicking the update button it should be update in the dropdown list but its not working
import React from "react";
export default function DropDown() {
const [input, setInput] = React.useState('');
const selectproject=({e})=>{
setInput(e.target.value);
}
return (
<>
<select>
<option>{input?input:'null'}</option>
</select>
<br/><br/>
<input value={input} /><button onClick={selectproject}>Update</button>
</>
);
}
remove curly braces on selectproject props.
selectproject=(e)=>{
setInput(e.target.value);
}
you are destructuring e in <Event> which is not available. if you want to destructuring it, try this instead
selectproject=({target: {value}})=>{
setInput(value);
}
if you want dropdown list to be updated after clicking button, you'll need another state
import React from "react";
export default function DropDown() {
const [input, setInput] = React.useState("");
const [project, setProject] = React.useState("");
const selectproject = () => {
setProject(input);
};
const handleOnChange = (e) => {
setInput(e.value.target);
};
return (
<>
<select>
<option>{project ? project : "null"}</option>
</select>
<br />
<br />
<input value={input} onChange={handleOnChange} />
<button onClick={selectproject}>Update</button>
</>
);
}
Need to remove curly brace around e and set onchange to input:
import React from "react";
export default function DropDown() {
const [input, setInput] = React.useState("");
const selectproject = (e) => {
setInput(e.target.value);
};
return (
<>
<select>
<option>{input ? input : "null"}</option>
</select>
<br />
<br />
<input value={input} onChange={selectproject} />
<button onClick= {selectproject}>Update</button>
</>
);
}
You can use from two useState:
import React from "react";
function DropDown() {
const [input, setInput] = React.useState('');
const [select,setSelect] = React.useState('');
const selectproject = () => {
setSelect(input);
}
const handleChange = (e) => {
setInput(e.target.value);
}
return (
<>
<select>
<option>{select?select:'null'}</option>
</select>
<br/><br/>
<input onChange={handleChange} value={input} /><button onClick={selectproject}>Update</button>
</>
);
}
I want to pass the Child component state to parent component state, I was done once in a class base component but in the functional component, it doesn't work anymore.
Here is my model below:
And that is the components
const Search = () => {
return(
<div>
<h1>Search Anything</h1>
<form>
<InuptForm />
<input type="submit">Search</input>
</form>
</div>
);
}
const InuptForm = () => {
const [search, setSearch] = React.useState('');
const handleChange = (e) => {
setSearch(e.target.value);
}
return(
<div>
<h1>Search Anything</h1>
<form>
<input type="text" name="search" value={search} onChange={handleChange} />
</form>
</div>
);
}
Or is there any chance to use useReducer hook to overcome the issue?
I would really appreciate it if anyone can help.
Thanks
you cant pass state upwards in React. it is one-directional. if you want the state in the parent you need to "lift the state up". that means place it in the parent component
do something like this:
const Search = ({ handleChange }) => {
return(
<div>
<h1>Search Anything</h1>
<form>
<input type="submit" onChange={handleChange}>Search</input>
</form>
</div>
);
}
const InuptForm = () => {
const [search, setSearch] = React.useState('');
const handleChange = (e) => {
setSearch(e.target.value);
}
return(
<div>
<Search handleChange={handleChange} />
</div>
);
}
I'm rendering <Search /> inside <InputForm /> here and then passing down the handleChange prop
States cannot be passed to Parent components from child component, instead what you can do is create state in parent component and then pass it as prop to child, so on change function in child will update state in parent component.
const Search = () => {
const [search, setSearch] = React.useState('');
const handleChange = (e) => {
setSearch(e.target.value);
}
return(
<div>
<h1>Search Anything</h1>
<form>
<InuptForm value={search} handler={handleChange} />
<input type="submit">Search</input>
</form>
</div>
);
}
const InuptForm = ({value, handler}) => {
return(
<div>
<h1>Search Anything</h1>
<form>
<input type="text" name="search" value={value} onChange={(e) => handler(e)} />
</form>
</div>
);
}
I have JSX element in my React code with value attribute which is not changing correctly with onChange method.
First I am using React Hooks:
const [isBusiness, setIsBusiness] = useState(false);
I am using this constant in my JSX:
<input
type="checkbox"
value={isBusiness} //here is the constant
id="isBusiness"
onChange={businessChange}
name="check"
/>
My onChange method is like this:
const businessChange = e => {
if (e.target.value == true) {
console.log(isBusiness);
setIsBusiness(false);
} else {
console.log(isBusiness);
setIsBusiness(true);
}
};
I am seeing what happens and it is stucking at true for some reason:
The idea is to be able to get value of this checkbox (true or false) if it is clicked or not. The initial value is false.
e.target.value == true will always be false, because e.target.value is a string. Your isBusiness will be converted to "true" or "false", and both "true" == true and "false" == true are false.
Typically, you rarely use value with checkboxes, and only use value with checkboxes if you're submitting a form somewhere; it provides the value to send (by default it's "on"). Instead, use checked:
<input
type="checkbox"
checked={isBusiness}
id="isBusiness"
onChange={businessChange}
name="check"
/>
Then
const businessChange = e => {
if (e.target.checked) {
console.log(isBusiness);
setIsBusiness(true);
} else {
console.log(isBusiness);
setIsBusiness(false);
}
};
Or simply:
const businessChange = e => {
console.log(isBusiness);
setIsBusiness(e.target.checked);
};
const {useState} = React;
const Example = () => {
const [isBusiness, setIsBusiness] = useState(false);
const businessChange = e => {
console.log(isBusiness);
setIsBusiness(e.target.checked);
};
return (
<input
type="checkbox"
checked={isBusiness}
id="isBusiness"
onChange={businessChange}
name="check"
/>
);
};
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
Note: It's slightly confusing with the logging, because you're always logging the old value. :-) Here's a version logging the new value:
const {useState} = React;
const Example = () => {
const [isBusiness, setIsBusiness] = useState(false);
const businessChange = e => {
console.log(e.target.checked);
setIsBusiness(e.target.checked);
};
return (
<input
type="checkbox"
checked={isBusiness}
id="isBusiness"
onChange={businessChange}
name="check"
/>
);
};
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
I would lean, however, toward not using the checkbox flag at all in the handler, as shown by keikai though they don't show correct setting of the checkbox. Here's a version logging the new value (not the old):
const {useState} = React;
const Example = () => {
const [isBusiness, setIsBusiness] = useState(false);
const businessChange = e => {
console.log(!isBusiness);
setIsBusiness(!isBusiness);
};
return (
<input
type="checkbox"
checked={isBusiness}
id="isBusiness"
onChange={businessChange}
name="check"
/>
);
};
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
You can set it proper and simple without using the event
const businessChange = () => {
setIsBusiness(!isBusiness);
};
const App = () => {
const [isBusiness, setIsBusiness] = React.useState(false);
const businessChange = () => {
console.log(!isBusiness);
setIsBusiness(!isBusiness);
};
return (
<div className="App">
<input
type="checkbox"
value={isBusiness} //here is the constant
id="isBusiness"
onChange={businessChange}
name="check"
/>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
I have a React Form app with name and description fields.
The form data is held in a local state object using Hooks:
const [data,setData] = useState({name: '', description: ''}).
The <Form /> element creates inputs and passes their value using <Field initialValue ={data.name} />
Within the <Field /> element, this initialValue is passed to the state, which controls the input value (updated onChange):
const [value,setValue] = useState(initialValue).
But if I reset the data object (see handleResetClick function), the inputs don't clear (even though the data object clears). What am I doing wrong? I thought that changing the data would cause a re-render and re-pass initialValue, resetting the input.
Codepen example here - when I type in the inputs, the data object updates, but when I click Clear, the inputs don't empty.
function Form() {
const [data, setData] = React.useState({name: '', description: ''});
React.useEffect(() => {
console.log(data);
},[data]);
const onSubmit = (e) => {
// not relevant to example
e.preventDefault();
return;
}
const handleResetClick = () => {
console.log('reset click');
setData({name: '', description: ''})
}
const onChange = (name, value) => {
const tmpData = data;
tmpData[name] = value;
setData({
...tmpData
});
}
return (
<form onSubmit={onSubmit}>
<Field onChange={onChange} initialValue={data.name} name="name" label="Name" />
<Field onChange={onChange} initialValue={data.description} name="description" label="Description" />
<button type="submit" className="button is-link">Submit</button>
<button onClick={handleResetClick} className="button is-link is-light">Clear</button>
</form>
)
}
function Field(props) {
const {name, label, initialValue, onChange} = props;
const [value, setValue] = React.useState(initialValue);
return (
<div>
<div className="field">
<label className="label">{label}</label>
<div className="control">
<input
name={name}
className="input"
type="text"
value={value}
onChange={e => {
setValue(e.target.value)
onChange(name, e.target.value)
}}
/>
</div>
</div>
</div>
)
}
class App extends React.Component {
render() {
return (
<div className="container">
<Form />
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
)
On handleResetClick you change the data state of Form, but it doesn't affect its children.
Try adding a listener for initialValue change with useEffect:
function Field(props) {
const { name, label, initialValue, onChange } = props;
const [value, setValue] = React.useState(initialValue);
useEffect(() => {
setValue(initialValue);
}, [initialValue]);
return ...
}
You may be better off having Field as a controlled component (ie it's state is managed by the parent component rather than maintaining its own state). In this example I've swapped in value instead of initialValue and simply passed that down as props to the field. onChange then calls the parent method and updates the state there (which is automatically passed back down to the field when it renders):
const { useState, useEffect } = React;
function Form() {
const [data, setData] = React.useState({
name: '',
description: ''
});
useEffect(() => {
console.log(data);
}, [data]);
const onSubmit = (e) => {
e.preventDefault();
return;
}
const handleResetClick = () => {
setData({name: '', description: ''})
}
const onChange = (e) => {
const { target: { name, value } } = e;
setData(data => ({ ...data, [name]: value }));
}
return (
<form onSubmit={onSubmit}>
<Field onChange={onChange} value={data.name} name="name" label="Name" />
<Field onChange={onChange} value={data.description} name="description" label="Description" />
<button type="submit" className="button is-link">Submit</button>
<button onClick={handleResetClick} className="button is-link is-light">Clear</button>
</form>
)
}
function Field(props) {
const {name, label, value, onChange} = props;
return (
<div>
<div className="field">
<label className="label">{label}</label>
<div className="control">
<input
name={name}
className="input"
type="text"
value={value}
onChange={onChange}
/>
</div>
</div>
</div>
)
}
function App() {
return (
<div className="container">
<Form />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>